home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Gfx / Edit / TSMorph / src / TSMorph.c < prev    next >
C/C++ Source or Header  |  1995-03-12  |  120KB  |  3,865 lines

  1. // TSMorph - Amiga Morphing program
  2. // Copyright (C) © 1993  Topicsave Limited
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mpaddock@cix.compulink.co.uk
  19.  
  20. // include normally precompiled headers if required
  21. #ifndef TSMORPH_H
  22. #include "TSMorph.h"
  23. #endif
  24.  
  25. /* Disable CTRL-C checking    */
  26. int CXBRK(void) { return(0); }
  27. int chkabort(void) { return(0); }
  28. int __regargs __chkabort(void) { return(0); }
  29.  
  30. /* Define all the Library bases    */
  31. struct IntuitionBase *IntuitionBase;
  32. struct Library    *GfxBase,
  33.                     *LayersBase,
  34.                     *InputBase,
  35.                     *IFFParseBase,
  36.                     *GadToolsBase,
  37.                     *AslBase,
  38.                     *UtilityBase,
  39.                     *DiskfontBase,
  40.                     *AmigaGuideBase,
  41.                     *IconBase,
  42.                     *ReqToolsBase,
  43.                     *RexxSysBase,
  44.                     *DCTVBase;
  45.  
  46. struct OpalBase *OpalBase;
  47.  
  48. struct Library *EGSIntuiBase = NULL;
  49. struct Library *EGSGfxBase = NULL;
  50. struct Library *EGSBase = NULL;
  51. struct Library *EGSRequestBase = NULL;
  52.  
  53. /* Table of system gadget sizes
  54.  * See TSMorph.h for definitions
  55.  */
  56. extern struct gadgetsizing gs[] = {
  57.     {SYSISIZE_LOWRES,13,11,16,11,13,11,16,11,13,11,15,18,18, 7, 9},
  58.     {SYSISIZE_MEDRES,18,10,16,10,18,11,16,10,18,11,20,24,24,10,13}
  59. };
  60.  
  61. extern UWORD                         Mode             = NONE;
  62. extern struct List                PointList     = {0};
  63. extern struct Picture             Pic1            = {0},
  64.                                         Pic2            = {0};
  65. extern BOOL                         Pic1_Open    = FALSE;
  66. extern BOOL                         Pic2_Open    = FALSE;
  67. extern struct FileRequester     *filereq        = NULL;
  68. //extern struct FileRequester     *sfilereq    = NULL;
  69. extern struct rtFileRequester    *rtfilereq    = NULL;
  70. extern BOOL                         Saved         = TRUE;
  71. char                         savedfilename[256]    = "";
  72. extern LONG                            Width            = 0,
  73.                                         Height        = 0;
  74. extern LONG                            SinglePicture            = 0;
  75. extern BOOL                         Zoom            = FALSE;
  76. extern BOOL                         ZoomAllowed    = TRUE;
  77. extern BOOL                            PaletteAllowed            = TRUE;
  78. extern char                         **ArgArray                = NULL;
  79. extern char                         **ArgArraySettings    = NULL;
  80. extern AMIGAGUIDECONTEXT         handle         = NULL;
  81. extern BOOL                            palette        = TRUE;
  82. extern BOOL                            CreateIcons = TRUE;
  83. extern BOOL                            CreateIconsR = FALSE;/* TRUE if to write Render Icons    */
  84. extern BOOL                            CreateIconsP = TRUE;    /* TRUE if to write prefs Icons    */
  85. extern BOOL                            KeepSettings = TRUE; /* TRUE to save settings on quit */
  86. extern ULONG                        DX=0;
  87. extern ULONG                        DY=0;
  88. char                            LoadScript[128] = "Rexx/Loadscript";
  89. char                            PreScript[128] = "Rexx/Prescript";
  90. char                            PostScript[128] = "Rexx/Postscript";
  91. char                            PreviewScript[128] = "Rexx/Preview";
  92. char                            ScreenName[128] = "";
  93. char                            ScreenNameR[128] = "";
  94. char                            CustomName[128] = "";
  95. extern ULONG                        CustomDepth = 4;
  96. extern BOOL                            OpenedScreen = FALSE;/* Did we open the screen            */
  97. extern ULONG                        Depth=2;
  98. extern ULONG                        RenderMode=0;
  99. extern ULONG                        SaveFormat=0;
  100. extern ULONG                        Quality=75;
  101. extern ULONG                        ASig            = 0;
  102. extern ULONG                        OpenMode        = 0;
  103. extern int                            changedboxcount    = 0;    // Used to redraw points after resizing BOTH windows
  104. extern UWORD                        n=0;                            // Holds screen resolution
  105. extern LONG                         MaxWidth        = 0;    // Max x of points
  106. extern LONG                            MaxHeight    = 0;    // Max y of points
  107. extern BOOL                            AntiAlias    = FALSE;    // Anti Alias?
  108. extern BOOL                            Integer        = FALSE;    // Integer calculation?
  109. extern BOOL                            GHelp            = FALSE;    // Gadget Help?
  110. extern struct NewAmigaGuide    nag     = {NULL};        // .guide stuff
  111. extern BOOL                            EGS = FALSE;        // Use EGS picture window
  112.  
  113. struct MsgPort        *WMsgPortp;            // Message port for Picture Windows
  114. ULONG                 IDCMPFlags;            // IDCMP flags for windows
  115. LONG                     Start;                // Start frame
  116.  
  117. /* Mapping for Boopsi gadgets    */
  118. struct TagItem MapToIdcmp[] = {
  119.     {PGA_Top,ICSPECIAL_CODE},
  120.     {GA_ID,ICSPECIAL_CODE},
  121.     {TAG_END,}
  122. };
  123.  
  124. /* Properties for IFF read    */
  125. extern LONG props[] = {    ID_ILBM,    ID_BMHD,    // Just need BitMapHeader
  126.                         ID_ILBM,    ID_CAMG,            // CAMG (not sure why)
  127.                         ID_ILBM, ID_CMAP,            // And ColourMap
  128.                         TAG_DONE };
  129.  
  130. extern LONG stops[] = {    ID_ILBM,    ID_BODY,    // Stop on Body chunk
  131.                         TAG_DONE };
  132.  
  133. extern LONG nowt[] = { TAG_DONE };            // Nothing else is required
  134.  
  135. extern LONG FrameNumber = 0;                    // Current frame number
  136.  
  137. /* Wait pointer */
  138. extern USHORT __chip BusyPointerData[] =
  139. {
  140.     0x0000,0x0000,
  141.     0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
  142.     0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
  143.     0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
  144.     0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
  145.     0x0000,0x0000,
  146. };
  147.  
  148.  
  149. /* Version string for CLI version */
  150. char *Version = "$VER: TSMorph 3.2 (12.3.95)";
  151.  
  152. /* Display About requester
  153.  * using reqtools.library if available
  154.  */
  155. void
  156. About(void) {
  157.     UBYTE *body;
  158.     UBYTE *title = "TSMorph 3.2 (12.3.95)";
  159.     UBYTE *gad;
  160.     struct EasyStruct EasyStruct = {
  161.           sizeof(struct EasyStruct),
  162.         0,
  163.         NULL,
  164.         NULL,
  165.         NULL
  166.     };
  167.     DisableWindows(DI_About);
  168.     body = MyGetMsg(MSG_ABOUT);
  169.     gad = MyGetMsg(MSG_OK);
  170.     if (ReqToolsBase) {
  171.         rtEZRequestTags(body,MyGetMsg(MSG__OK),NULL,NULL,
  172.                             RT_Window,        TSMorphWnd,
  173.                             RTEZ_ReqTitle,    title,
  174.                             RTEZ_Flags,        EZREQF_CENTERTEXT,
  175.                             RT_Underscore,    '_',
  176.                             TAG_END);
  177.     }
  178.     else {
  179.         EasyStruct.es_Title = title;
  180.         EasyStruct.es_TextFormat = body;
  181.         EasyStruct.es_GadgetFormat = gad;
  182.         EasyRequestArgs(TSMorphWnd,&EasyStruct,NULL,NULL);
  183.     }
  184.     EnableWindows();
  185. }
  186.  
  187. /* The main procedure    */
  188. int
  189. main(int argc,char **argv) {
  190.  BOOL                 OkFlag        = FALSE;        // Still running ok
  191.  struct IOStdReq    InputIO;                        // Input device to check Shift key
  192.  struct Message     *Message;                    // To discard messages from ports
  193.  struct WBStartup *argmsg;                        // Workbench stuff
  194.  struct WBArg         *wb_arg;                        // Workbench arguments
  195.  struct Window        *oldWindowPtr;                // Retain old pointer for system requesters
  196.  struct Process    *process;                    // This process for system requesters
  197.  char                 *e                = NULL;        // Main error message string
  198.  char                 *e1            = NULL;        // Variable part of error message
  199.  char                 *filename;                    // General file name
  200.  LONG                    hnum            = 0;            // Help to display on an error message
  201.  
  202.  /* Initalise list of points    */
  203.  NewList(&PointList);
  204.  // try and open optional libraries
  205.  DCTVBase = OpenLibrary("dctv.library",3L);
  206.  OpalBase = (struct OpalBase *)OpenLibrary("opal.library",0L);
  207.  ReqToolsBase = OpenLibrary("reqtools.library",38);
  208.  /* If we can open amigaguide.library
  209.   * then set up the help stuff
  210.   */
  211.  if (AmigaGuideBase = OpenLibrary ("amigaguide.library", 34L)) {
  212.   nag.nag_BaseName        = "TSMorph";
  213.   nag.nag_Name                = "TSMorph.guide";
  214.   nag.nag_ClientPort        = "TSMorph_HELP";
  215.   nag.nag_Context            = context;
  216.   nag.nag_Flags            = HTF_NOACTIVATE;
  217.   nag.nag_PubScreen        = NULL;
  218.   if (handle = OpenAmigaGuideAsync(&nag, NULL)) {
  219.    ASig = AmigaGuideSignal(handle);
  220.   }
  221.  }
  222.  /* Open all the libraries/devices/message ports/file requesters etc.    */
  223.  if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37L)) {
  224.   if (RexxSysBase = OpenLibrary("rexxsyslib.library",0L)) {
  225.   if (IconBase = OpenLibrary("icon.library",37L)) {
  226.    if (IFFParseBase = OpenLibrary("iffparse.library",37L)) {
  227.     if (!OpenDevice("input.device",NULL,(struct IORequest *)&InputIO,NULL)) {
  228.      InputBase = (struct Library *)InputIO.io_Device;
  229.      if (GfxBase = OpenLibrary("graphics.library",37L)) {
  230.       if (LayersBase = OpenLibrary("layers.library",37L)) {
  231.        if (GadToolsBase = OpenLibrary("gadtools.library",37L)) {
  232.         if (AslBase = OpenLibrary("asl.library",37L)) {
  233.          if (UtilityBase = OpenLibrary("utility.library",37)) {
  234.           if (DiskfontBase = OpenLibrary("diskfont.library",36)) {
  235.            if (WMsgPortp = CreateMsgPort()) {
  236.             /* Read all the parameters/tooltypes/settings file    */
  237.             MyArgArrayInit(argc,argv);
  238.             InitParams(TRUE);
  239.             if (MatchToolValue(MyArgString("REQTOOLS","YES",FALSE),"NO")) {
  240.              if (ReqToolsBase) {
  241.               CloseLibrary(ReqToolsBase);
  242.               ReqToolsBase = NULL;
  243.              }
  244.             }
  245.             if (MatchToolValue(MyArgString("EGS","NO",FALSE),"YES")) {
  246.              if ((EGSBase = OpenLibrary("egs.library",0)) &&
  247.                  (EGSGfxBase = OpenLibrary("egsgfx.library", 0)) &&
  248.                  (EGSIntuiBase = OpenLibrary("egsintui.library", 0)) &&
  249.                  (EGSRequestBase = OpenLibrary("egsrequest.library", 0))) {
  250.               EGS = TRUE;
  251.               ZoomAllowed = FALSE;
  252.              }
  253.             }
  254.             if ((MatchToolValue(MyArgString("REQTOOLS","YES",FALSE),"ALL") &&
  255.                 (rtfilereq = (struct rtFileRequester *)rtAllocRequestA(RT_FILEREQ,NULL))) ||
  256.                 (filereq = (struct FileRequester *)AllocFileRequest())) {
  257.               /* Open custom screen if required                */
  258.               if (OpenCustomScreen()) {
  259.                if (PubScreenName && *PubScreenName) {
  260.                 /* Since the screen now exists reopen amigaguide on it! */
  261.                 if (handle) {
  262.                  CloseAmigaGuide(handle);
  263.                  handle = NULL;
  264.                 }
  265.                 if (AmigaGuideBase) {
  266.                  nag.nag_PubScreen        = PubScreenName;
  267.                  if (handle = OpenAmigaGuideAsync(&nag, NULL)) {
  268.                   ASig = AmigaGuideSignal(handle);
  269.                  }
  270.                 }
  271.                }
  272.                /* Update the Info window menus and open    */
  273.                if (!SetupScreen()) {
  274.                 if (!OpenTSMorphWindow()) {
  275.                  /* Set up system requester redirection    */
  276.                  process = (struct Process *)FindTask(NULL);
  277.                  oldWindowPtr = process->pr_WindowPtr;
  278.                  process->pr_WindowPtr = TSMorphWnd;
  279.                  /* Activate the window and disable        */
  280.                  ActivateWindow(TSMorphWnd);
  281.                  DisableWindows(DI_LoadBrush);
  282.                  /* Load brushes if possible                    */
  283.                  LoadBrushes();
  284.                  /* No filename as yet                            */
  285.                     *savedfilename = 0;
  286.                     if (argc) {
  287.                     if (filename = ArgString(ArgArray,"FILES",NULL)) {
  288.                    MyOpen(filename,FALSE,TRUE);                // From the CLI and FILES parameter supplied
  289.                   }
  290.                  }
  291.                  else {
  292.                     argmsg = (struct WBStartup *)argv;
  293.                          if (argmsg->sm_NumArgs > 1) {
  294.                      wb_arg = argmsg->sm_ArgList;
  295.                      wb_arg++;
  296.                      if (wb_arg->wa_Lock) {
  297.                         NameFromLock(wb_arg->wa_Lock,savedfilename,256);
  298.                        }
  299.                       if (AddPart(savedfilename,wb_arg->wa_Name,256)) {
  300.                        MyOpen(savedfilename,FALSE,TRUE);        // From the WB and project supplied
  301.                      }
  302.                     }
  303.                  }
  304.                  /* Enable the windows and do the main stuff    */
  305.                  EnableWindows();
  306.                  doMsgLoop();
  307.                  if (KeepSettings) {
  308.                   SaveSettings("ENV:TSMorph/TSMorph.prefs");    // save settings for next run
  309.                  }
  310.                  /* Close everything down in reverse order
  311.                   * Setting up error message if required
  312.                   */
  313.                  if (Pic1_Open) {
  314.                   CloseAPicture(&Pic1);
  315.                   Pic1_Open = FALSE;
  316.                  }
  317.                  if (Pic2_Open) {
  318.                   CloseAPicture(&Pic2);
  319.                   Pic2_Open = FALSE;
  320.                  }
  321.                  DeleteAllPoints();
  322.                  if (ControlWindow) {
  323.                   CloseControlWindow();
  324.                  }
  325.                  process->pr_WindowPtr = oldWindowPtr;
  326.                  OkFlag = TRUE;
  327.                 }
  328.                 CloseTSMorphWindow();
  329.                 if (!OkFlag && !e) {
  330.                  e = MyGetMsg(MSG_FAILURE);                    // e and e1 to save memory as e is reused
  331.                  e1 = MyGetMsg(MSG_OTSMW);
  332.                  hnum = HE_OMorph;
  333.                 }
  334.                }
  335.                CloseDownScreen();
  336.                if (!OkFlag && !e) {
  337.                 e = MyGetMsg(MSG_FAILURE);
  338.                 e1 = MyGetMsg(MSG_SUSCR);
  339.                 hnum = HE_Screen;
  340.                }
  341.               }
  342.               else {
  343.                // Displayed error message elsewhere
  344.                OkFlag = TRUE;
  345.               }
  346.               MyArgArrayDone();
  347.               if (rtfilereq) {
  348.                rtFreeRequest(rtfilereq);
  349.               }
  350.               else {
  351.                FreeFileRequest(filereq);
  352.               }
  353.             }
  354.             if (!OkFlag && !e) {
  355.              e = MyGetMsg(MSG_UNABLE);
  356.              e1 = MyGetMsg(MSG_FILER);
  357.              hnum = HE_FileReq;
  358.             }
  359.             Forbid();
  360.             while (Message = GetMsg(WMsgPortp)) {
  361.              ReplyMsg(Message);
  362.             }
  363.             DeleteMsgPort(WMsgPortp);
  364.             Permit();
  365.            }
  366.            if (!OkFlag && !e) {
  367.             e = MyGetMsg(MSG_UNABLE);
  368.             e1 = MyGetMsg(MSG_CWMP);
  369.             hnum = HE_WPort;
  370.            }
  371.            CloseLibrary(DiskfontBase);
  372.           }
  373.           if (!OkFlag && !e) {
  374.            e = MyGetMsg(MSG_CANNOTOP);
  375.            e1= "diskfont.library(36)";
  376.            hnum = HE_Library;
  377.                }
  378.           CloseLibrary(UtilityBase);
  379.          }
  380.          if (!OkFlag && !e) {
  381.           e = MyGetMsg(MSG_CANNOTOP);
  382.           e1 = "utility.library(37)";
  383.           hnum = HE_Library;
  384.          }
  385.          CloseLibrary(AslBase);
  386.         }
  387.         if (!OkFlag && !e) {
  388.          e = MyGetMsg(MSG_CANNOTOP);
  389.          e1 = "asl.library(37)";
  390.          hnum = HE_Library;
  391.         }
  392.         CloseLibrary(GadToolsBase);
  393.        }
  394.        if (!OkFlag && !e) {
  395.         e = MyGetMsg(MSG_CANNOTOP);
  396.         e1 = "gadtools.library(37)";
  397.         hnum = HE_Library;
  398.        }
  399.        CloseLibrary(LayersBase);
  400.       }
  401.       if (!OkFlag && !e) {
  402.        e = MyGetMsg(MSG_CANNOTOP);
  403.        e1 = "layers.library(37)";
  404.        hnum = HE_Library;
  405.       }
  406.       CloseLibrary(GfxBase);
  407.      }
  408.      if (!OkFlag && !e) {
  409.       e = MyGetMsg(MSG_CANNOTOP);
  410.       e1 = "graphics.library(37)";
  411.       hnum = HE_Library;
  412.      }
  413.      CloseDevice(&InputIO);
  414.     }
  415.     if (!OkFlag && !e) {
  416.      e = MyGetMsg(MSG_CANNOTOP);
  417.      e1 = "input.device";
  418.      hnum = HE_IDevice;
  419.     }
  420.     CloseLibrary(IFFParseBase);
  421.    }
  422.    if (!OkFlag && !e) {
  423.     e = MyGetMsg(MSG_CANNOTOP);
  424.     e1 = "iffparse.library(37)";
  425.     hnum = HE_Library;
  426.    }
  427.      CloseLibrary(IconBase);
  428.   }
  429.   if (!OkFlag && !e) {
  430.    e = MyGetMsg(MSG_CANNOTOP);
  431.    e1 = "icon.library(37)";
  432.    hnum = HE_Library;
  433.   }
  434.      CloseLibrary(RexxSysBase);
  435.   }
  436.   if (!OkFlag && !e) {
  437.    e = MyGetMsg(MSG_CANNOTOP);
  438.    e1 = "rexxsyslib.library(0)";
  439.    hnum = HE_Library;
  440.   }
  441.   if (!OkFlag) {
  442.    Error(e,MyGetMsg(MSG_QUIT),e1,hnum);            // Display error message if it failed
  443.   }
  444.   /* Close AmigaGuide (so we can close the screen)
  445.    * It will be reopened if required
  446.    */
  447.   if (handle) {
  448.    CloseAmigaGuide(handle);
  449.    handle = NULL;
  450.    ASig = NULL;
  451.   }
  452.   if (OpenedScreen) {
  453.    CloseCustomScreen();
  454.   }
  455.  }
  456.  if (EGSRequestBase) {
  457.   CloseLibrary(EGSRequestBase);
  458.  }
  459.  if (EGSIntuiBase) {
  460.   CloseLibrary(EGSIntuiBase);
  461.  }
  462.  if (EGSGfxBase) {
  463.   CloseLibrary(EGSGfxBase);
  464.  }
  465.  if (EGSBase) {
  466.   CloseLibrary(EGSBase);
  467.  }
  468.  if (AmigaGuideBase) {
  469.   CloseLibrary(AmigaGuideBase);
  470.  }
  471.  if (OpalBase) {
  472.   CloseLibrary((struct Library *)OpalBase);
  473.  }
  474.  if (ReqToolsBase) {
  475.   CloseLibrary(ReqToolsBase);
  476.  }
  477.  if (DCTVBase) {
  478.   CloseLibrary(DCTVBase);
  479.  }
  480.  if (IntuitionBase) {
  481.   CloseLibrary((struct Library *)IntuitionBase);
  482.  }
  483.  return 0;
  484. }
  485.  
  486. /* Open and image in a window
  487.  * returns    : TRUE or FALSE for sucess failure
  488.  * filename    : Name of file, can be NULL in which case ASL file requester is displayed
  489.  * pic        : pointer to a structure to hold all the stuff
  490.  * GUI        : TRUE or FALSE to display error message on failure
  491.  */
  492. BOOL
  493. openAPicture(char *filename,struct Picture *pic,BOOL GUI) {
  494.  char dirname[257];    // full filename from ASL requester or FrameNumber
  495.  char rtfilename[108] = "\0";    // reqtools filename from requester
  496.  char *ifilename    = NULL;    // filename to use
  497.  char *e             = NULL;    // first part of error message
  498.  char *e1             = NULL;    // 2nd part of error message
  499.  int i;                            // Loop counter for bit planes
  500.  LONG hnum            = 0;        // Help number for error
  501.  struct EI_NewWindow EGS_NewWindow = {0};    // EGS New window
  502.  /* Set file name from input supplied
  503.   * or by using ASL file requester
  504.   */
  505.  if (filename) {
  506.   if ((SinglePicture == 2) || (SinglePicture == 3)) {
  507.    sprintf(dirname,filename,FrameNumber);        // Add in frame number
  508.    ifilename = dirname;
  509.   }
  510.   else {
  511.    ifilename = filename;
  512.   }
  513.  }
  514.  else {
  515.   if (rtfilereq) {
  516.    if (rtFileRequestA(rtfilereq,rtfilename,MyGetMsg(MSG_PICKIFF),NULL)) {
  517.     strncpy(dirname,rtfilereq->Dir,256);
  518.     if (AddPart(dirname,rtfilename,256)) {
  519.      ifilename=dirname;
  520.     }
  521.    }
  522.   }
  523.   else {
  524.    if (AslRequestTags((APTR) filereq,ASL_Hail,(Tag) MyGetMsg(MSG_PICKIFF),TAG_DONE)) {
  525.     strncpy(dirname,filereq->rf_Dir,256);
  526.     if (AddPart(dirname,filereq->rf_File,256)) {
  527.      ifilename=dirname;
  528.     }
  529.    }
  530.   }
  531.  }
  532.  /* If we now have a file name then find the screen (passed in PUBSCREEN=)
  533.   * determine its resolution and get some data
  534.   */
  535.  if (ifilename) {
  536.   if (pic->Screen = LockPubScreen(PubScreenName)) {
  537.    if (pic->DRI = GetScreenDrawInfo(pic->Screen)) {
  538.     /* Load the image using IFF stuff
  539.      * and do some validation and set some gadgets
  540.      */
  541.     if (pic->ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  542.      if (!MyLoadBrush(pic,ifilename)) {
  543.       e = (char *)-1;
  544.       GUI = FALSE;    // already displayed message
  545.      }
  546.      else {
  547.       if (!EGS) {
  548.        pic->width = pic->ilbm->Bmhd.w;
  549.        pic->height = pic->ilbm->Bmhd.h;
  550.       }
  551.       if (pic == &Pic1) {
  552.          if ((Pic1.width < MaxWidth) ||
  553.               (Pic1.height < MaxHeight)) {
  554.         e = MyGetMsg(MSG_IMSMALL);
  555.         hnum = HE_ISmall;
  556.        }
  557.       }
  558.       else {
  559.        if ((Pic1.width != Pic2.width) ||
  560.            (Pic1.height != Pic2.height)) {
  561.         e = MyGetMsg(MSG_IMDIFF);
  562.         hnum = HE_IDifferent;
  563.        }
  564.        else {
  565.         Width = Pic1.width;
  566.         Height = Pic1.height;
  567.           GT_SetGadgetAttrs(TSMorphGadgets[GDX_Width],TSMorphWnd,NULL,
  568.                                 GTNM_Number,Width,
  569.                                 TAG_END );
  570.           GT_SetGadgetAttrs(TSMorphGadgets[GDX_Height],TSMorphWnd,NULL,
  571.                                 GTNM_Number,Height,
  572.                                 TAG_END );
  573.        }
  574.       }
  575.       /* If Zoom is allowed then we always display the Zoom bitmap
  576.        * This is either 2x the normal bit map or just use the top left corner
  577.        */
  578.       if (!e) {
  579.        if (ZoomAllowed) {
  580.         InitBitMap(&(pic->BitMap),min(min(pic->ilbm->Bmhd.nPlanes,8),pic->Screen->BitMap.Depth),pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1);
  581.            for (i=0;
  582.                  (i < pic->ilbm->Bmhd.nPlanes) && (i < 8) && (i < pic->Screen->BitMap.Depth) && !e; // Allow up to 8 bitplanes
  583.                  ++i) {
  584.            if (!(pic->BitMap.Planes[i] = AllocRaster(pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1))) {
  585.           e = MyGetMsg(MSG_UNALLOC);
  586.           e1 = MyGetMsg(MSG_ZOOMR);
  587.           hnum = HE_ZRaster;
  588.          }
  589.           }
  590.           if (!e) {
  591.            pic->BitScaleArgs.bsa_SrcX         = 0;
  592.            pic->BitScaleArgs.bsa_SrcY         = 0;
  593.            pic->BitScaleArgs.bsa_SrcWidth     = pic->ilbm->Bmhd.w;
  594.            pic->BitScaleArgs.bsa_SrcHeight     = pic->ilbm->Bmhd.h;
  595.            pic->BitScaleArgs.bsa_DestX         = 0;
  596.            pic->BitScaleArgs.bsa_DestY         = 0;
  597.            pic->BitScaleArgs.bsa_DestWidth     = pic->ilbm->Bmhd.w<<1;
  598.            pic->BitScaleArgs.bsa_DestHeight = pic->ilbm->Bmhd.h<<1;
  599.            pic->BitScaleArgs.bsa_XSrcFactor = 1;
  600.            pic->BitScaleArgs.bsa_XDestFactor= 2;
  601.            pic->BitScaleArgs.bsa_YSrcFactor = 1;
  602.            pic->BitScaleArgs.bsa_YDestFactor= 2;
  603.            pic->BitScaleArgs.bsa_SrcBitMap     = pic->ilbm->brbitmap;
  604.            pic->BitScaleArgs.bsa_DestBitMap = &(pic->BitMap);
  605.            pic->BitScaleArgs.bsa_Flags         = 0;
  606.            /* Either scale image 2x or straight copy    */
  607.             if (Zoom) {
  608.              BitMapScale(&(pic->BitScaleArgs));
  609.             }
  610.            else {
  611.             BltBitMap(pic->ilbm->brbitmap,0,0,
  612.                            &(pic->BitMap),0,0,
  613.                            pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
  614.                            0xC0,0xff,NULL);
  615.            }
  616.           }
  617.          }
  618.         }
  619.       if (!e) {
  620.        pic->Left = 0;    //    Need to do this as Pic structures can be closed and reopened
  621.        pic->Top = 0;
  622.        if (EGS) {
  623.         if (pic->filename = AllocVec(strlen(ifilename)+1+20,MEMF_PUBLIC|MEMF_CLEAR)) {    // Extra for other frames
  624.          strcpy(pic->filename,ifilename);
  625.          EGS_NewWindow.LeftEdge = (pic == &Pic1)?0:
  626.                      max(min(Pic1.EGS_Win->Width + Pic1.EGS_Win->BorderLeft + Pic1.EGS_Win->BorderRight,
  627.                          Pic1.EGS_Win->WScreen->Width - Pic1.EGS_Win->Width - Pic1.EGS_Win->BorderLeft - Pic1.EGS_Win->BorderRight),0);
  628.          EGS_NewWindow.TopEdge = (pic == &Pic1)?20:
  629.                        max(min(Pic1.EGS_Win->Height + Pic1.EGS_Win->BorderTop + Pic1.EGS_Win->BorderBottom + 16,
  630.                          Pic1.EGS_Win->WScreen->Height - Pic1.EGS_Win->Height - Pic1.EGS_Win->BorderTop - Pic1.EGS_Win->BorderBottom - 16),0);
  631.          EGS_NewWindow.Width = pic->width;
  632.          EGS_NewWindow.Height = pic->height;
  633.          EGS_NewWindow.MinWidth = 20;
  634.          EGS_NewWindow.MinHeight = 20;
  635.          EGS_NewWindow.MaxWidth = pic->width;
  636.          EGS_NewWindow.MaxHeight = pic->height;
  637.          EGS_NewWindow.Screen = NULL;
  638.          EGS_NewWindow.Bordef.SysGadgets = EI_WINDOWCLOSE | EI_WINDOWSIZE | EI_WINDOWFRONT | EI_WINDOWFLIP |
  639.                                                         EI_WINDOWARROWL | EI_WINDOWARROWR | EI_WINDOWARROWU | EI_WINDOWARROWD |
  640.                                                         EI_WINDOWSCROLLH | EI_WINDOWSCROLLV | EI_WINDOWDRAG;
  641.          EGS_NewWindow.FirstGadgets = NULL;
  642.          EGS_NewWindow.Title = FilePart(pic->filename);
  643.          EGS_NewWindow.Flags = EI_GIMMEZEROZERO | EI_SUPER_BITMAP | EI_WINDOWACTIVE | EI_REPORTMOUSE | EI_QUICKSCROLL | EI_RMBTRAP;
  644.          EGS_NewWindow.IDCMPFlags = EI_iCLOSEWINDOW | EI_iVANILLAKEY | EI_iMOUSEBUTTONS | EI_iMOUSEMOVE | EI_iACTIVEWINDOW | EI_iNEWSIZE;
  645.          EGS_NewWindow.Port = WMsgPortp;
  646. //       EGS_NewWindow.Colors = ??;
  647.          EGS_NewWindow.Menu = NULL;
  648.          EGS_NewWindow.Render = NULL;
  649.          if (pic->EGS_Win = EI_OpenWindow(&EGS_NewWindow)) {
  650. //        EI_ReportMouse(pic->EGS_Win,TRUE);
  651.           EI_SetWindowTitles(pic->EGS_Win,(UBYTE *)-1,pic->filename);
  652.           pic->EGS_Win->UserData  = (BYTE *)pic;
  653.           if (pic == &Pic2) {
  654.            E_ActivateEGSScreen();
  655.           }
  656.           EG_CopyBitMapRastPort(pic->EGS_BitMap,pic->EGS_Win->RPort,0,0,pic->width,pic->height,0,0);
  657.           E_DisposeBitMap(pic->EGS_BitMap);
  658.           pic->EGS_BitMap = NULL;
  659.           EG_SetDrMd(pic->EGS_Win->RPort,EG_INVERT);
  660.           if (pic == &Pic1) {
  661.            E_ActivateAmigaScreen();
  662.            ScreenToFront(Scr);
  663.           }
  664.           return TRUE;
  665.          }
  666.          if (!e) {
  667.           e = MyGetMsg(MSG_UNABLE);
  668.           e1 = MyGetMsg(MSG_OPENW);
  669.           hnum = HE_OWindow;
  670.          }
  671.         }
  672.         if (!e) {
  673.          e = MyGetMsg(MSG_UNABLE);
  674.          e1 = MyGetMsg(MSG_ALLOCFIL);
  675.          hnum = HE_MemFile;
  676.         }
  677.        }
  678.        else {
  679.         /* Allocate all gadgets and images    */
  680.         if (pic->BotGad = (struct Gadget *)NewObject(NULL,"propgclass",
  681.           PGA_Freedom,        FREEHORIZ,
  682.           PGA_NewLook,        TRUE,
  683.           PGA_Borderless,    (pic->Screen->BitMap.Depth>1)?TRUE:FALSE,
  684.           PGA_Top,                pic->Left,
  685.           PGA_Visible,        pic->ilbm->Bmhd.w<<Zoom,
  686.           PGA_Total,            pic->ilbm->Bmhd.w<<Zoom,
  687.           ICA_TARGET,            ICTARGET_IDCMP,
  688.           GA_Left,                pic->Screen->WBorLeft - 1,
  689.           GA_Height,            SIZEIMAGE_H(n) - 4,
  690.           GA_RelBottom,        -SIZEIMAGE_H(n) + 3,
  691.           GA_RelWidth,        -(SIZEIMAGE_W(n)+LEFTIMAGE_W(n)+RIGHTIMAGE_W(n)+pic->Screen->WBorLeft+1),
  692.           GA_ID,                LEFT_RIGHT_GADGET,
  693.           GA_GZZGadget,        TRUE,
  694.           GA_Immediate,        TRUE,
  695.           GA_RelVerify,        TRUE,
  696.           GA_BottomBorder,    TRUE,
  697.           ICA_MAP,                MapToIdcmp,
  698.           GA_UserData,        pic,
  699.           TAG_END)) {
  700.          if (pic->SideGad = (struct Gadget *)NewObject(NULL,"propgclass",
  701.            PGA_Freedom,        FREEVERT,
  702.            PGA_NewLook,        TRUE,
  703.            PGA_Borderless,    (pic->Screen->BitMap.Depth>1)?TRUE:FALSE,
  704.            PGA_Top,            pic->Top,
  705.            PGA_Visible,        pic->ilbm->Bmhd.h<<Zoom,
  706.            PGA_Total,            pic->ilbm->Bmhd.h<<Zoom,
  707.            ICA_TARGET,        ICTARGET_IDCMP,
  708.            GA_Top,                pic->Screen->WBorTop + pic->Screen->Font->ta_YSize + 2,
  709.            GA_Width,            VSCROLL_W(n),
  710.            GA_RelRight,        -VSCROLL_L(n),
  711.            GA_RelHeight,        -(pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+3+UPIMAGE_H(n)+DOWNIMAGE_H(n)+SIZEIMAGE_H(n)),
  712.            GA_ID,                UP_DOWN_GADGET,
  713.            GA_GZZGadget,        TRUE,
  714.            GA_Immediate,        TRUE,
  715.            GA_RelVerify,        TRUE,
  716.            GA_RightBorder,    TRUE,
  717.            GA_Previous,        pic->BotGad,
  718.            ICA_MAP,            MapToIdcmp,
  719.            GA_UserData,        pic,
  720.            TAG_END)) {
  721.           if (pic->Limage = (struct Image *)NewObject(NULL,"sysiclass",
  722.             SYSIA_DrawInfo,    pic->DRI,
  723.             SYSIA_Which,        LEFTIMAGE,
  724.             SYSIA_Size,        SYSISIZE(n),
  725.             TAG_END)) {
  726.            if (pic->Rimage = (struct Image *)NewObject(NULL,"sysiclass",
  727.              SYSIA_DrawInfo,pic->DRI,
  728.              SYSIA_Which,    RIGHTIMAGE,
  729.              SYSIA_Size,        SYSISIZE(n),
  730.              TAG_END)) {
  731.             if (pic->Dimage = (struct Image *)NewObject(NULL,"sysiclass",
  732.               SYSIA_DrawInfo,    pic->DRI,
  733.               SYSIA_Which,        DOWNIMAGE,
  734.               SYSIA_Size,        SYSISIZE(n),
  735.               TAG_END)) {
  736.              if (pic->Uimage = (struct Image *)NewObject(NULL,"sysiclass",
  737.                SYSIA_DrawInfo,    pic->DRI,
  738.                SYSIA_Which,        UPIMAGE,
  739.                SYSIA_Size,        SYSISIZE(n),
  740.                TAG_END)) {
  741.               if (pic->Lgad = (struct Gadget *)NewObject(NULL,"buttongclass",
  742.                 ICA_TARGET,            ICTARGET_IDCMP,
  743.                 GA_RelRight,        -(SIZEIMAGE_W(n)+RIGHTIMAGE_W(n)+LEFTIMAGE_W(n)-1),
  744.                 GA_RelBottom,        -SIZEIMAGE_H(n)+1,
  745.                 GA_Height,            LEFTIMAGE_H(n),
  746.                 GA_Width,            LEFTIMAGE_W(n),
  747.                 GA_ID,                LEFT_GADGET,
  748.                 GA_GZZGadget,        TRUE,
  749.                 GA_Immediate,        TRUE,
  750.                 GA_RelVerify,        TRUE,
  751.                 GA_BottomBorder,    TRUE,
  752.                 GA_Previous,        pic->SideGad,
  753.                 ICA_MAP,                MapToIdcmp,
  754.                 GA_Image,            pic->Limage,
  755.                 GA_UserData,        pic,
  756.                 TAG_END)) {
  757.                if (pic->Rgad = (struct Gadget *)NewObject(NULL,"buttongclass",
  758.                  ICA_TARGET,        ICTARGET_IDCMP,
  759.                  GA_RelRight,        -(SIZEIMAGE_W(n)+RIGHTIMAGE_W(n)-1),
  760.                  GA_RelBottom,        -SIZEIMAGE_H(n)+1,
  761.                  GA_Height,            LEFTIMAGE_H(n),
  762.                  GA_Width,            LEFTIMAGE_W(n),
  763.                  GA_ID,                RIGHT_GADGET,
  764.                  GA_GZZGadget,        TRUE,
  765.                  GA_Immediate,        TRUE,
  766.                  GA_RelVerify,        TRUE,
  767.                  GA_BottomBorder,    TRUE,
  768.                  GA_Previous,        pic->Lgad,
  769.                  ICA_MAP,            MapToIdcmp,
  770.                  GA_Image,            pic->Rimage,
  771.                  GA_UserData,        pic,
  772.                  TAG_END)) {
  773.                 if(pic->Ugad = (struct Gadget *)NewObject(NULL,"buttongclass",
  774.                   ICA_TARGET,        ICTARGET_IDCMP,
  775.                   GA_RelRight,        -SIZEIMAGE_W(n)+1,
  776.                   GA_RelBottom,    -(SIZEIMAGE_H(n)+UPIMAGE_H(n)+DOWNIMAGE_H(n)-1),
  777.                   GA_Height,        UPIMAGE_H(n),
  778.                   GA_Width,            UPIMAGE_W(n),
  779.                   GA_ID,                UP_GADGET,
  780.                   GA_GZZGadget,    TRUE,
  781.                   GA_Immediate,    TRUE,
  782.                   GA_RelVerify,    TRUE,
  783.                   GA_RightBorder,    TRUE,
  784.                   GA_Previous,        pic->Rgad,
  785.                   ICA_MAP,            MapToIdcmp,
  786.                   GA_Image,            pic->Uimage,
  787.                   GA_UserData,        pic,
  788.                   TAG_END)) {
  789.                  if (pic->Dgad = (struct Gadget *)NewObject(NULL,"buttongclass",
  790.                    ICA_TARGET,            ICTARGET_IDCMP,
  791.                    GA_RelRight,        -SIZEIMAGE_W(n)+1,
  792.                    GA_RelBottom,        -(SIZEIMAGE_H(n)+DOWNIMAGE_H(n)-1),
  793.                    GA_Height,            DOWNIMAGE_H(n),
  794.                    GA_Width,            DOWNIMAGE_W(n),
  795.                    GA_ID,                DOWN_GADGET,
  796.                    GA_GZZGadget,        TRUE,
  797.                    GA_Immediate,        TRUE,
  798.                    GA_RelVerify,        TRUE,
  799.                    GA_RightBorder,    TRUE,
  800.                    GA_Previous,        pic->Ugad,
  801.                    ICA_MAP,                MapToIdcmp,
  802.                    GA_Image,            pic->Dimage,
  803.                    GA_UserData,        pic,
  804.                    TAG_END)) {
  805.                    /* Set up size of shrunk window    */
  806.                    pic->Zoom.Left     = 0;
  807.                    pic->Zoom.Top         = pic->Screen->Font->ta_YSize+1;
  808.                    pic->Zoom.Width     = max(ZOOMIMAGE_W(n)+DEPTHIMAGE_W(n)+CLOSEIMAGE_W(n)+1,
  809.                                                     pic->Screen->WBorLeft+SIZEIMAGE_W(n)+LEFTIMAGE_W(n)+RIGHTIMAGE_W(n)+7);
  810.                    pic->Zoom.Height     = pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+
  811.                                              SIZEIMAGE_H(n)+UPIMAGE_H(n)+DOWNIMAGE_H(n)+8;
  812.                   /* Copy filename for title and open the window */
  813.                   if (pic->filename     = AllocVec(strlen(ifilename)+1+20,MEMF_PUBLIC|MEMF_CLEAR)) {    // Extra for other frames
  814.                    strcpy(pic->filename,ifilename);
  815.                    if (pic->Win = OpenWindowTags(NULL,
  816.                      WA_Width,            (pic->ilbm->Bmhd.w<<Zoom)+
  817.                                              pic->Screen->WBorLeft+SIZEIMAGE_W(n),
  818.                      WA_Height,        (pic->ilbm->Bmhd.h<<Zoom)+
  819.                                              pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n),
  820.                      WA_AutoAdjust,    TRUE,
  821.                      WA_MaxWidth,        (pic->ilbm->Bmhd.w<<Zoom)+
  822.                                              pic->Screen->WBorLeft+SIZEIMAGE_W(n),
  823.                      WA_MaxHeight,    (pic->ilbm->Bmhd.h<<Zoom)+
  824.                                              pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n),
  825.                      WA_MinWidth,        pic->Zoom.Width,
  826.                      WA_MinHeight,    pic->Zoom.Height,
  827.                      WA_IDCMP,            0,
  828.                      WA_Flags,            WFLG_SIZEGADGET | WFLG_SIZEBRIGHT | WFLG_SIZEBBOTTOM |
  829.                                           WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
  830.                                           WFLG_SUPER_BITMAP + WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH,
  831.                      WA_Gadgets,        pic->BotGad,
  832.                      WA_Title,            FilePart(pic->filename),
  833.                      WA_ScreenTitle,    pic->filename,
  834.                      WA_PubScreen,    pic->Screen,
  835.                      WA_SuperBitMap,    (ZoomAllowed ? &(pic->BitMap) : pic->ilbm->brbitmap),
  836.                      /* Open image 1 to the right of the control window
  837.                       * Image 2 to the bottom right of the 1st image
  838.                       */
  839.                      WA_Left,             ((pic == &Pic1)?
  840.                                                  ControlWindow->Width:
  841.                                                  ControlWindow->Width+Pic1.Win->Width),
  842.                      WA_Top,             ((pic == &Pic1)?
  843.                                                  ControlWindow->TopEdge:
  844.                                                  Pic1.Win->Height+Pic1.Win->TopEdge),
  845.                             WA_MenuHelp,        TRUE,
  846.                             WA_NewLookMenus,TRUE,
  847.                      TAG_DONE)) {
  848.                     // Enable gadget Help if possible
  849.                            if (IntuitionBase->LibNode.lib_Version > 38) {
  850.                      HelpControl(pic->Win,HC_GADGETHELP);
  851.                     }
  852.                     /* Set user data to determine window
  853.                      * and use shared message port
  854.                     */
  855.                     pic->Win->UserData  = (BYTE *)pic;
  856.                     pic->Win->UserPort    = WMsgPortp;
  857.                     IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  858.                                  IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  859.                                  IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
  860.                                  IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  861.                                  IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  862.                                  IDCMP_GADGETHELP;
  863.                     ModifyIDCMP(pic->Win,IDCMPFlags);
  864.                     pic->Win->Flags |= WFLG_REPORTMOUSE;
  865.                           /* Set mode to draw and erase points easily    */
  866.                           SetDrMd(pic->Win->RPort,COMPLEMENT);
  867.                           /* Set the (shared with Control Window) menu
  868.                            * and do some size calculations
  869.                            */
  870.                           if (SetMenuStrip(pic->Win,MyMenu)) {
  871.                      doNewSize(pic);
  872.                      return (TRUE);                            // It all worked !!!
  873.                     }
  874.                     /* Set relevant error message    */
  875.                     if (!e) {
  876.                      e = MyGetMsg(MSG_UNABLE);
  877.                      e1 = MyGetMsg(MSG_SETMENU);
  878.                      hnum = HE_Menu;
  879.                     }
  880.                    }
  881.                    if (!e) {
  882.                     e = MyGetMsg(MSG_UNABLE);
  883.                     e1 = MyGetMsg(MSG_OPENW);
  884.                     hnum = HE_OWindow;
  885.                    }
  886.                   }
  887.                   if (!e) {
  888.                    e = MyGetMsg(MSG_UNABLE);
  889.                    e1 = MyGetMsg(MSG_ALLOCFIL);
  890.                    hnum = HE_MemFile;
  891.                   }
  892.                  }
  893.                  if (!e) {
  894.                   e = MyGetMsg(MSG_UNALLOC);
  895.                   e1 = MyGetMsg(MSG_DOWNG);
  896.                   hnum = HE_AllocGadget;
  897.                  }
  898.                 }
  899.                 if (!e) {
  900.                  e = MyGetMsg(MSG_UNALLOC);
  901.                  e1 = MyGetMsg(MSG_UPG);
  902.                  hnum = HE_AllocGadget;
  903.                 }
  904.                }
  905.                if (!e) {
  906.                 e = MyGetMsg(MSG_UNALLOC);
  907.                 e1 = MyGetMsg(MSG_RIGHTG);
  908.                 hnum = HE_AllocGadget;
  909.                }
  910.               }
  911.               if (!e) {
  912.                e = MyGetMsg(MSG_UNALLOC);
  913.                e1 = MyGetMsg(MSG_LEFTG);
  914.                hnum = HE_AllocGadget;
  915.               }
  916.              }
  917.              if (!e) {
  918.               e = MyGetMsg(MSG_UNALLOC);
  919.               e1 = MyGetMsg(MSG_UPI);
  920.               hnum = HE_AllocImage;
  921.              }
  922.             }
  923.             if (!e) {
  924.              e = MyGetMsg(MSG_UNALLOC);
  925.              e1 = MyGetMsg(MSG_DOWNI);
  926.              hnum = HE_AllocImage;
  927.             }
  928.            }
  929.            if (!e) {
  930.             e = MyGetMsg(MSG_UNALLOC);
  931.             e1 = MyGetMsg(MSG_RIGHTI);
  932.             hnum = HE_AllocImage;
  933.            }
  934.           }
  935.           if (!e) {
  936.            e = MyGetMsg(MSG_UNALLOC);
  937.            e1 = MyGetMsg(MSG_LEFTI);
  938.            hnum = HE_AllocImage;
  939.           }
  940.          }
  941.          if (!e) {
  942.           e = MyGetMsg(MSG_UNALLOC);
  943.           e1 = MyGetMsg(MSG_VGAD);
  944.           hnum = HE_AllocGadget;
  945.          }
  946.         }
  947.         if (!e) {
  948.          e = MyGetMsg(MSG_UNALLOC);
  949.          e1 = MyGetMsg(MSG_HGAD);
  950.          hnum = HE_AllocGadget;
  951.         }
  952.        }
  953.       }
  954.      }
  955.     }
  956.     if (!e) {
  957.      e = MyGetMsg(MSG_UNABLE);
  958.      e1 = MyGetMsg(MSG_ALLOCILB);
  959.      hnum = HE_AllocILBM;
  960.     }
  961.    }
  962.    if (!e) {
  963.     e = MyGetMsg(MSG_UNABLE);
  964.     e1 = MyGetMsg(MSG_GETSDI);
  965.     hnum = HE_GetDRI;
  966.    }
  967.   }
  968.   if (!e) {
  969.    e = MyGetMsg(MSG_LOCKPUBS);
  970.    e1 = PubScreenName;
  971.    hnum = HE_LockScreen;
  972.   }
  973.   /* Clear everything down
  974.    * and display an error message if requested
  975.    */
  976.   CloseAPicture(pic);
  977.   if (GUI)
  978.    Error(e,MyGetMsg(MSG_OK),e1,hnum);
  979.  }
  980.  return(FALSE);
  981. }
  982.  
  983. /* Close a (partially open)
  984.  * picture, clearing everything
  985.  * down in reverse order
  986.  */
  987. void
  988. CloseAPicture(struct Picture *pic) {
  989.     int i;    // Loop counter for bitmaps
  990.     if (pic) {
  991.         if (EGS) {
  992.             if (pic->EGS_Win) {
  993.                 EI_CloseWindow(pic->EGS_Win);
  994.                 pic->EGS_Win = NULL;
  995.             }
  996.             if (pic->EGS_BitMap) {
  997.                 E_DisposeBitMap(pic->EGS_BitMap);
  998.                 pic->EGS_BitMap = NULL;
  999.             }
  1000.         }
  1001.         if (pic->Win) {
  1002.             ClearMenuStrip(pic->Win);
  1003.             CloseWindowSafely(pic->Win);
  1004.             pic->Win = NULL;
  1005.         }
  1006.         if (pic->filename) {
  1007.             FreeVec(pic->filename);
  1008.             pic->filename = NULL;
  1009.         }
  1010.         if (pic->Dgad) {
  1011.             DisposeObject(pic->Dgad);
  1012.             pic->Dgad = NULL;
  1013.         }
  1014.         if (pic->Ugad) {
  1015.             DisposeObject(pic->Ugad);
  1016.             pic->Ugad = NULL;
  1017.         }
  1018.         if (pic->Rgad) {
  1019.             DisposeObject(pic->Rgad);
  1020.             pic->Rgad = NULL;
  1021.         }
  1022.         if (pic->Lgad) {
  1023.             DisposeObject(pic->Lgad);
  1024.             pic->Lgad = NULL;
  1025.         }
  1026.         if (pic->Uimage) {
  1027.             DisposeObject(pic->Uimage);
  1028.             pic->Uimage = NULL;
  1029.         }
  1030.         if (pic->Dimage) {
  1031.             DisposeObject(pic->Dimage);
  1032.             pic->Dimage = NULL;
  1033.         }
  1034.         if (pic->Rimage) {
  1035.             DisposeObject(pic->Rimage);
  1036.             pic->Rimage = NULL;
  1037.         }
  1038.         if (pic->Limage) {
  1039.             DisposeObject(pic->Limage);
  1040.             pic->Limage = NULL;
  1041.         }
  1042.         if (pic->SideGad) {
  1043.             DisposeObject(pic->SideGad);
  1044.             pic->SideGad = NULL;
  1045.         }
  1046.         if (pic->BotGad) {
  1047.             DisposeObject(pic->BotGad);
  1048.             pic->BotGad = NULL;
  1049.         }
  1050.         if (ZoomAllowed) {
  1051.             for (i=0;
  1052.                 (i < pic->ilbm->Bmhd.nPlanes) && (i < 8);
  1053.                 ++i) {
  1054.                 if (pic->BitMap.Planes[i]) {
  1055.                     FreeRaster(pic->BitMap.Planes[i],pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1);
  1056.                     pic->BitMap.Planes[i] = NULL;
  1057.                 }
  1058.             }
  1059.         }
  1060.         if (pic->ilbm) {
  1061.             unloadbrush(pic->ilbm);
  1062.             if (pic->ilbm->ParseInfo.iff) {
  1063.                 FreeIFF(pic->ilbm->ParseInfo.iff);
  1064.             }
  1065.             FreeMem(pic->ilbm,sizeof(struct ILBMInfo));
  1066.             pic->ilbm = NULL;
  1067.         }
  1068.         if (pic->Screen) {
  1069.             if (pic->DRI) {
  1070.                 FreeScreenDrawInfo(pic->Screen,pic->DRI);
  1071.                 pic->DRI = NULL;
  1072.             }
  1073.             UnlockPubScreen(NULL,pic->Screen);
  1074.             pic->Screen = NULL;
  1075.         }
  1076.     }
  1077. }
  1078.  
  1079. /* After opening or resizing a window
  1080.  * this does various gadget recalculations
  1081.  */
  1082. void
  1083. doNewSize(struct Picture *pic) {
  1084.     ULONG tmp;
  1085.     /* If window made wider then may need to scroll image
  1086.      * right to prevent gap on the right
  1087.      */
  1088.     tmp = pic->Win->RPort->Layer->Scroll_X + pic->Win->GZZWidth;
  1089.     if (tmp >= (pic->ilbm->Bmhd.w<<Zoom)) {
  1090.         ScrollLayer(0,pic->Win->RPort->Layer,(pic->ilbm->Bmhd.w<<Zoom)-tmp,0);
  1091.         pic->Left += (pic->ilbm->Bmhd.w<<Zoom)-tmp;
  1092.     }
  1093.     /* Update sideways gadget and recalculate movement */
  1094.     SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  1095.         PGA_Visible, pic->Win->GZZWidth,
  1096.         PGA_Top, pic->Left, TAG_END);
  1097.     pic->ALeft = pic->Win->GZZWidth/10;
  1098.     pic->MLeft = (pic->ilbm->Bmhd.w<<Zoom) - pic->Win->GZZWidth;
  1099.     /* If window made taller then may need to scroll image
  1100.      * down to prevent gap at the bottom
  1101.      */
  1102.     tmp = pic->Win->RPort->Layer->Scroll_Y + pic->Win->GZZHeight;
  1103.     if (tmp >= (pic->ilbm->Bmhd.h<<Zoom)) {
  1104.         ScrollLayer(0,pic->Win->RPort->Layer,0,(pic->ilbm->Bmhd.h<<Zoom)-tmp);
  1105.         pic->Top += (pic->ilbm->Bmhd.h<<Zoom)-tmp;
  1106.     }
  1107.     /* Update vertical gadget and recalculate movement */
  1108.     SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  1109.         PGA_Visible, pic->Win->GZZHeight,
  1110.         PGA_Top, pic->Top, TAG_END);
  1111.     pic->ATop = pic->Win->GZZHeight/10;
  1112.     pic->MTop = (pic->ilbm->Bmhd.h<<Zoom) - pic->Win->GZZHeight;
  1113. }
  1114.  
  1115. /* Scroll the image when required */
  1116. void
  1117. checkGadget(struct Picture *pic) {
  1118.     WORD dX;
  1119.     WORD dY;
  1120.     if (!EGS) {
  1121.         dY = pic->Top-pic->XTop;
  1122.         dX = pic->Left-pic->XLeft;
  1123.         if (dX || dY) {
  1124.             ScrollLayer(0,pic->Win->RPort->Layer,dX,dY);
  1125.         }
  1126.     }
  1127. }
  1128.  
  1129. /* Draw a point and linked lines if required
  1130.  * if MyPoint is not supplied the just draw the point
  1131.  */
  1132. VOID
  1133. DrawPixels(struct Picture *pic,SHORT x,SHORT y,struct MyPoint *MyPoint) {
  1134.     SHORT zx,zy;
  1135.     int i;
  1136.     if (EGS) {
  1137.         /* draw 3x3 point
  1138.          */
  1139.         zx = x;
  1140.         zy = y;
  1141.         EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy-2);
  1142.         EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy-2);
  1143.         EG_WritePixel(pic->EGS_Win->RPort,zx,zy-2);
  1144.         EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy-2);
  1145.         EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy-2);
  1146.         EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy-1);
  1147.         EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy-1);
  1148.         EG_WritePixel(pic->EGS_Win->RPort,zx,zy-1);
  1149.         EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy-1);
  1150.         EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy-1);
  1151.         EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy);
  1152.         EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy);
  1153.         EG_WritePixel(pic->EGS_Win->RPort,zx,zy);
  1154.         EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy);
  1155.         EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy);
  1156.         EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy+1);
  1157.         EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy+1);
  1158.         EG_WritePixel(pic->EGS_Win->RPort,zx,zy+1);
  1159.         EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy+1);
  1160.         EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy+1);
  1161.         EG_WritePixel(pic->EGS_Win->RPort,zx-2,zy+2);
  1162.         EG_WritePixel(pic->EGS_Win->RPort,zx-1,zy+2);
  1163.         EG_WritePixel(pic->EGS_Win->RPort,zx,zy+2);
  1164.         EG_WritePixel(pic->EGS_Win->RPort,zx+1,zy+2);
  1165.         EG_WritePixel(pic->EGS_Win->RPort,zx+2,zy+2);
  1166.         /* Draw linked lines in the correct window if MyPoint supplied
  1167.          * Note: EGSMyDraw is like EG_Draw only it always draws top left to bottom right
  1168.          *         to prevent problems when erasing lines in the other direction
  1169.          */
  1170.         if (pic == &Pic2) {
  1171.             if (MyPoint) {
  1172.                 for (i = 0;
  1173.                       i < MAX_LINKS;
  1174.                       i++) {
  1175.                     if (MyPoint->p[i]) {
  1176.                         EGSMyDraw(pic->EGS_Win->RPort,MyPoint->p[i]->x1,MyPoint->p[i]->y1,zx,zy);
  1177.                     }
  1178.                 }
  1179.             }
  1180.         }
  1181.         else {
  1182.             if (MyPoint) {
  1183.                 for (i = 0;
  1184.                       i < MAX_LINKS;
  1185.                       i++) {
  1186.                     if (MyPoint->p[i]) {
  1187.                         EGSMyDraw(pic->EGS_Win->RPort,MyPoint->p[i]->x,MyPoint->p[i]->y,zx,zy);
  1188.                     }
  1189.                 }
  1190.             }
  1191.         }
  1192.     }
  1193.     else {
  1194.         /* Scale coordinates if zoomed
  1195.          * and draw 3x3 point
  1196.          */
  1197.         zx = x << Zoom;
  1198.         zy = y << Zoom;
  1199.         WritePixel(pic->Win->RPort,zx-2,zy-2);
  1200.         WritePixel(pic->Win->RPort,zx-1,zy-2);
  1201.         WritePixel(pic->Win->RPort,zx,zy-2);
  1202.         WritePixel(pic->Win->RPort,zx+1,zy-2);
  1203.         WritePixel(pic->Win->RPort,zx+2,zy-2);
  1204.         WritePixel(pic->Win->RPort,zx-2,zy-1);
  1205.         WritePixel(pic->Win->RPort,zx-1,zy-1);
  1206.         WritePixel(pic->Win->RPort,zx,zy-1);
  1207.         WritePixel(pic->Win->RPort,zx+1,zy-1);
  1208.         WritePixel(pic->Win->RPort,zx+2,zy-1);
  1209.         WritePixel(pic->Win->RPort,zx-2,zy);
  1210.         WritePixel(pic->Win->RPort,zx-1,zy);
  1211.         WritePixel(pic->Win->RPort,zx,zy);
  1212.         WritePixel(pic->Win->RPort,zx+1,zy);
  1213.         WritePixel(pic->Win->RPort,zx+2,zy);
  1214.         WritePixel(pic->Win->RPort,zx-2,zy+1);
  1215.         WritePixel(pic->Win->RPort,zx-1,zy+1);
  1216.         WritePixel(pic->Win->RPort,zx,zy+1);
  1217.         WritePixel(pic->Win->RPort,zx+1,zy+1);
  1218.         WritePixel(pic->Win->RPort,zx+2,zy+1);
  1219.         WritePixel(pic->Win->RPort,zx-2,zy+2);
  1220.         WritePixel(pic->Win->RPort,zx-1,zy+2);
  1221.         WritePixel(pic->Win->RPort,zx,zy+2);
  1222.         WritePixel(pic->Win->RPort,zx+1,zy+2);
  1223.         WritePixel(pic->Win->RPort,zx+2,zy+2);
  1224.         /* Draw linked lines in the correct window if MyPoint supplied
  1225.          * Note: MyDraw is like Draw only it always draws top left to bottom right
  1226.          *         to prevent problems when erasing lines in the other direction
  1227.          */
  1228.         if (pic == &Pic2) {
  1229.             if (MyPoint) {
  1230.                 for (i = 0;
  1231.                       i < MAX_LINKS;
  1232.                       i++) {
  1233.                     if (MyPoint->p[i]) {
  1234.                         MyDraw(pic->Win->RPort,MyPoint->p[i]->x1<<Zoom,MyPoint->p[i]->y1<<Zoom,zx,zy);
  1235.                     }    
  1236.                 }
  1237.             }
  1238.         }
  1239.         else {
  1240.             if (MyPoint) {
  1241.                 for (i = 0;
  1242.                       i < MAX_LINKS;
  1243.                       i++) {
  1244.                     if (MyPoint->p[i]) {
  1245.                         MyDraw(pic->Win->RPort,MyPoint->p[i]->x<<Zoom,MyPoint->p[i]->y<<Zoom,zx,zy);
  1246.                     }
  1247.                 }
  1248.             }
  1249.         }
  1250.     }
  1251. }    
  1252.  
  1253. /* Delete all points
  1254.  * Erasing them if images are open
  1255.  */
  1256. void
  1257. DeleteAllPoints(void) {
  1258.     struct MyPoint *MyPoint;
  1259.     /* Loop round looking at the first point every time
  1260.      * since DeletePoint removes it from the list
  1261.      */
  1262.     while ((MyPoint = (struct MyPoint *)PointList.lh_Head)->MyNode.mln_Succ) {
  1263.         if (Pic1_Open) {
  1264.             DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  1265.         }
  1266.         if (Pic2_Open) {
  1267.             DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  1268.         }
  1269.         DeletePoint(MyPoint);
  1270.     }
  1271. }
  1272.  
  1273. /* Open a project
  1274.  * Suggests you save first if not already saved
  1275.  * Returns        : TRUE or FALSE for how well it went
  1276.  * filename        : file name to open - if NULL then display ASL file requeseter
  1277.  * JustPoints    : If TRUE then only the points are used
  1278.  * Gui         : Display error messages
  1279.  */
  1280. BOOL
  1281. MyOpen(char *filename,BOOL JustPoints,BOOL Gui) {
  1282.     LONG PointCount    = 0;        // Number of points read
  1283.     LONG i;                            // General loop counter
  1284.     char *ifilename    = NULL;    // File name to use
  1285.     BOOL ok                = TRUE;    // Is it all working?
  1286.     BPTR fh;                            // File handle
  1287.     char buffer[257];                // Buffer to read records
  1288.     LONG w=0,h=0;                    // Width and Height
  1289.     LONG x,x1,y,y1;                // Coordinates in image 1 and 2
  1290.     LONG p1,p2;                        // Index to linked points
  1291.     LONG Frames;                    // Number of frames
  1292.     struct MyPoint *MyPoint,    // Points to create and link
  1293.                         *MyPoint1;
  1294.     BOOL JP = FALSE;                // Set if 2.0 points file
  1295.     /* If current project not saved then suggest it is saved    */
  1296.     if (!Saved) {
  1297.         if (!SaveRequester()) {
  1298.             return ok;
  1299.         }
  1300.         DisableWindows(DI_WaitOpen);
  1301.     }
  1302.     /* Get filename, from parameter or ASL requester, save name for saving later */
  1303.     if (filename) {
  1304.         ifilename = filename;
  1305.         if (!JustPoints) {
  1306.             strncpy(savedfilename,filename,256);
  1307.         }
  1308.     }
  1309.     else {
  1310.         if (GetAFile(*savedfilename?savedfilename:"",
  1311.                          (Tag) JustPoints ? MyGetMsg(MSG_LOADPO): MyGetMsg(MSG_LOADPR),
  1312.                          0)) {
  1313.             ifilename=TempFilename;
  1314.             if (!JustPoints) {
  1315.                 strncpy(savedfilename,TempFilename,256);
  1316.             }
  1317.         }
  1318.       }
  1319.       /* If we have a filename then delete current points and set the window title    */
  1320.     if (ifilename) {
  1321.         if (!JustPoints) {
  1322.             OpenNewArgs(ifilename);        // Load new parameters
  1323.             InitParams(FALSE);
  1324.         }
  1325.         DeleteAllPoints();
  1326.         SetWindowTitles(TSMorphWnd,(UBYTE *)-1,savedfilename);
  1327.         if (fh=Open(ifilename,MODE_OLDFILE)) {
  1328.             // Get header
  1329.             FGets(fh,buffer,256);
  1330.             if (JustPoints && (JP = !strcmp(buffer,"TSMorph 2.0\n"))) {
  1331.                 DeleteAllPoints();
  1332.             }
  1333.             else {
  1334.                 if (strcmp(buffer,"TSMorph 1.2\n")) {
  1335.                     Error(MyGetMsg(MSG_VERS10),MyGetMsg(MSG_OK),NULL,HE_OldFormat);
  1336.                 }
  1337.                 else {
  1338.                     // Name of first image
  1339.                     FGets(fh,buffer,256);
  1340.                 }
  1341.             }
  1342.             if (!JustPoints) {
  1343.                 if (strlen(buffer)) {
  1344.                     buffer[strlen(buffer)-1]=0;
  1345.                 }
  1346.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,
  1347.                                         GTST_String, buffer, TAG_END );
  1348.             }
  1349.             // Name of second image
  1350.             if (!JP) {
  1351.                 FGets(fh,buffer,256);
  1352.                 if (!JustPoints) {
  1353.                     if (strlen(buffer)) {
  1354.                         buffer[strlen(buffer)-1]=0;
  1355.                     }
  1356.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,
  1357.                                             GTST_String, buffer, TAG_END );
  1358.                 }
  1359.                 // 24 bit name of first image
  1360.                 FGets(fh,buffer,256);
  1361.                 if (!JustPoints) {
  1362.                     if (strlen(buffer)) {
  1363.                         buffer[strlen(buffer)-1]=0;
  1364.                     }
  1365.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,
  1366.                                             GTST_String, buffer, TAG_END );
  1367.                 }
  1368.                 // 24 bit name of second image
  1369.                 FGets(fh,buffer,256);
  1370.                 if (!JustPoints) {
  1371.                     if (strlen(buffer)) {
  1372.                         buffer[strlen(buffer)-1]=0;
  1373.                     }
  1374.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,
  1375.                                             GTST_String, buffer, TAG_END );
  1376.                 }
  1377.                 // Name of animation
  1378.                 FGets(fh,buffer,256);
  1379.                 if (!JustPoints) {
  1380.                     if (strlen(buffer)) {
  1381.                         buffer[strlen(buffer)-1]=0;
  1382.                     }
  1383.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,
  1384.                                             GTST_String, buffer, TAG_END );
  1385.                 }
  1386.                 // General stuff
  1387.                 FGets(fh,buffer,256);
  1388.                 if (!JustPoints) {
  1389.                     if (ok && (sscanf(buffer,"w=%ld,h=%ld,Frames=%ld,Single=%ld,Start=%ld",&w,&h,&Frames,&SinglePicture,&Start) != 5)) {
  1390.                         Error(MyGetMsg(MSG_INVLINE),MyGetMsg(MSG_OK),buffer,HE_FileFormat);
  1391.                         ok = FALSE;
  1392.                     }
  1393.                     else {
  1394.                         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,
  1395.                                                 GTIN_Number,Frames, TAG_END );
  1396.                         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,
  1397.                                                     GTIN_Number,Start, TAG_END );
  1398.                         GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,
  1399.                                                 GTCY_Active,SinglePicture, TAG_END );
  1400.                         if (ok && ControlWindow &&
  1401.                                 ((w > Pic1.ilbm->Bmhd.w) ||
  1402.                              (h > Pic1.ilbm->Bmhd.h))) {
  1403.                             Error(MyGetMsg(MSG_ITOOSM),MyGetMsg(MSG_OK),NULL,HE_TooSmall);
  1404.                             ok = FALSE;
  1405.                         }
  1406.                     }
  1407.                 }
  1408.             }
  1409.             if (ok) {
  1410.                 MaxWidth     = 0;
  1411.                 MaxHeight     = 0;
  1412.                 // Read and validate point
  1413.                 while (ok &&
  1414.                     FGets(fh,buffer,256) &&
  1415.                     (sscanf(buffer,"x=%ld,y=%ld,x1=%ld,y1=%ld",&x,&y,&x1,&y1) == 4)) {
  1416.                     if (Pic1_Open) {
  1417.                         if ((x<0)||(x>(Pic1.ilbm->Bmhd.w-1)) ||
  1418.                              (y<0)||(y>(Pic1.ilbm->Bmhd.h-1))) {
  1419.                             Error(MyGetMsg(MSG_POOR),MyGetMsg(MSG_OK),buffer,HE_Range);
  1420.                             ok = FALSE;
  1421.                         }
  1422.                     }
  1423.                     // Create point and add to list
  1424.                     if (MyPoint = AllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
  1425.                         MyPoint->x = x;
  1426.                         MyPoint->y = y;
  1427.                         MyPoint->x1 = x1;
  1428.                         MyPoint->y1 = y1;
  1429.                         MaxWidth = max(x,MaxWidth);
  1430.                         MaxWidth = max(x1,MaxWidth);
  1431.                         MaxHeight = max(y,MaxHeight);
  1432.                         MaxHeight = max(y1,MaxHeight);
  1433.                         AddTail(&PointList,(struct Node *)MyPoint);
  1434.                         ++PointCount;
  1435.                         if (ControlWindow) {
  1436.                             // If the windows are open then actually draw the points
  1437.                             DrawPixels(&Pic1,x,y,MyPoint);
  1438.                             DrawPixels(&Pic2,x1,y1,MyPoint);
  1439.                         }
  1440.                     }
  1441.                     else {
  1442.                         Error(MyGetMsg(MSG_OOMPO),MyGetMsg(MSG_OK),NULL,HE_MemPoints);
  1443.                         ok=FALSE;
  1444.                     }
  1445.                 }
  1446.                 Width = max(w,MaxWidth);
  1447.                 Height = max(h,MaxHeight);
  1448.                 if (Pic1_Open) {
  1449.                     Width = max(Width,Pic1.width);
  1450.                     Height = max(Height,Pic1.height);
  1451.                 }
  1452.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_Width],TSMorphWnd,NULL,
  1453.                                         GTNM_Number,Width, TAG_END );
  1454.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_Height],TSMorphWnd,NULL,
  1455.                                         GTNM_Number,Height, TAG_END );
  1456.                 // Read all the links
  1457.                 while (ok &&
  1458.                     (sscanf(buffer,"p1=%ld,p2=%ld",&p1,&p2) == 2)) {
  1459.                     if ((p1>PointCount) || (p2>PointCount)) {
  1460.                         Error(MyGetMsg(MSG_INVPOLI),MyGetMsg(MSG_OK),buffer,HE_InvLink);
  1461.                         ok = FALSE;
  1462.                     }
  1463.                     else {
  1464.                         // Link two points based on indexes to linked lists
  1465.                         i = 0;
  1466.                         MyPoint = (struct MyPoint *)PointList.lh_Head;
  1467.                         while (i < p1) {
  1468.                             MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ;
  1469.                             ++i;
  1470.                         }
  1471.                         i = 0;
  1472.                         MyPoint1 = (struct MyPoint *)PointList.lh_Head;
  1473.                         while (i < p2) {
  1474.                             MyPoint1 = (struct MyPoint *)MyPoint1->MyNode.mln_Succ;
  1475.                             ++i;
  1476.                         }
  1477.                         LinkPoints(MyPoint,MyPoint1);
  1478.                     }
  1479.                     if (!FGets(fh,buffer,256)) {
  1480.                         ok = FALSE;
  1481.                     }
  1482.                 }
  1483.             }
  1484.             // Close file and return cleanly
  1485.             if (!Close(fh)) {
  1486.                 if (ok) {
  1487.                     Error(MyGetMsg(MSG_ECLOF),MyGetMsg(MSG_OK),ifilename,HE_Close);
  1488.                     ok = FALSE;
  1489.                 }
  1490.             }
  1491.         }
  1492.         else {
  1493.             if (Gui) {
  1494.                 Error(MyGetMsg(MSG_EOPF),MyGetMsg(MSG_OK),ifilename,HE_Open);
  1495.             }
  1496.             ok = FALSE;
  1497.         }
  1498.     }
  1499.     if (ok && !JustPoints) {
  1500.         Saved = TRUE;
  1501.     }
  1502.     else {
  1503.         if (ok && JustPoints) {
  1504.             Saved = FALSE;
  1505.         }
  1506.     }
  1507.     return ok;
  1508. }
  1509.  
  1510. /* Saves a project
  1511.  * Returns        : TRUE or FALSE for how well it went
  1512.  * filename        : file name to open - if NULL then display ASL file requeseter
  1513.  */
  1514. BOOL
  1515. SaveAs(char *filename) {
  1516.     char buffer[257];                // buffer to write records
  1517.     char *ifilename    = NULL;    // File name to use
  1518.     BPTR fh;                            // File handle
  1519.     LONG i,                            // Loop counters
  1520.           j,
  1521.           k;
  1522.     BOOL ok;                            // How well is it going
  1523.     struct MyPoint *MyPoint,    // Points to write
  1524.                         *MyPoint1;
  1525.     struct DiskObject *MyDiskObject;    // The Icon
  1526.     /* Set up the file name from the parameter or using and ASL requester    */
  1527.     if (filename && *filename) {
  1528.         ifilename = filename;
  1529.         strncpy(savedfilename,filename,256);
  1530.     }
  1531.     else {
  1532.         if (GetAFile(*savedfilename?savedfilename:"",MyGetMsg(MSG_SAVEP),FILF_SAVE)) {
  1533.             ifilename=TempFilename;
  1534.             strncpy(savedfilename,TempFilename,256);
  1535.         }
  1536.       }
  1537.       /* If we have a file name then set the window title
  1538.        * and write out the fixed information
  1539.        */
  1540.     if (ifilename) {
  1541.         SetWindowTitles(TSMorphWnd,(UBYTE *)-1,savedfilename);
  1542.         if (fh=Open(ifilename,MODE_NEWFILE)) {
  1543.             FPuts(fh,"TSMorph 1.2\n");
  1544.             FPuts(fh,GetString(TSMorphGadgets[GDX_FileOne]));
  1545.             FPuts(fh,"\n");
  1546.             FPuts(fh,GetString(TSMorphGadgets[GDX_FileTwo]));
  1547.             FPuts(fh,"\n");
  1548.             FPuts(fh,GetString(TSMorphGadgets[GDX_File241]));
  1549.             FPuts(fh,"\n");
  1550.             if ((SinglePicture == 0) || (SinglePicture == 2)) {
  1551.                 FPuts(fh,GetString(TSMorphGadgets[GDX_File242]));
  1552.             }
  1553.             FPuts(fh,"\n");
  1554.             FPuts(fh,GetString(TSMorphGadgets[GDX_Name]));
  1555.             FPuts(fh,"\n");
  1556.             sprintf(buffer,"w=%ld,h=%ld,Frames=%ld,Single=%ld,Start=%ld\n",
  1557.                     Width,Height,GetNumber(TSMorphGadgets[GDX_Frames]),SinglePicture,GetNumber(TSMorphGadgets[GDX_Start]));
  1558.             ok = !FPuts(fh,buffer);
  1559.             if ((SinglePicture == 2) || (SinglePicture == 3)) {
  1560.                 if (ControlWindow) {
  1561.                     if (!Close(fh)) {
  1562.                         if (ok) {
  1563.                             Error(MyGetMsg(MSG_ECLOF),MyGetMsg(MSG_OK),ifilename,HE_Close);
  1564.                             ok = FALSE;
  1565.                         }
  1566.                     }
  1567.                     strcpy(buffer,ifilename);
  1568.                     strcat(buffer,".%03ld");
  1569.                     sprintf(TempFilename,buffer,FrameNumber);
  1570.                     ifilename = TempFilename;
  1571.                     if (fh=Open(ifilename,MODE_NEWFILE)) {
  1572.                         FPuts(fh,"TSMorph 2.0\n");
  1573.                     }
  1574.                     else {
  1575.                         Error(MyGetMsg(MSG_EOPF),MyGetMsg(MSG_OK),ifilename,HE_Open);
  1576.                         ok = FALSE;
  1577.                     }
  1578.                 }
  1579.             }
  1580.             // Write out all the points
  1581.             for (MyPoint = (struct MyPoint *)PointList.lh_Head;
  1582.                     MyPoint->MyNode.mln_Succ && ok;
  1583.                     MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
  1584.                 sprintf(buffer,"x=%ld,y=%ld,x1=%ld,y1=%ld\n",MyPoint->x,MyPoint->y,MyPoint->x1,MyPoint->y1);
  1585.                 ok = !FPuts(fh,buffer);
  1586.             }
  1587.             // Write out all the links
  1588.             i = 0;
  1589.             for (MyPoint = (struct MyPoint *)PointList.lh_Head;
  1590.                     MyPoint->MyNode.mln_Succ && ok;
  1591.                     MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
  1592.                 j = 0;
  1593.                 for (MyPoint1= (struct MyPoint *)PointList.lh_Head;
  1594.                         MyPoint1->MyNode.mln_Succ;
  1595.                         MyPoint1 = (struct MyPoint *)MyPoint1->MyNode.mln_Succ) {
  1596.                     // Only write each link once
  1597.                     if (j>i) {
  1598.                         for (k = 0;
  1599.                               k < MAX_LINKS;
  1600.                               k++) {
  1601.                             if (MyPoint->p[k] == MyPoint1) {
  1602.                                 sprintf(buffer,"p1=%ld,p2=%ld\n",i,j);
  1603.                                 ok = !FPuts(fh,buffer);
  1604.                             }
  1605.                         }
  1606.                     }
  1607.                     ++j;
  1608.                 }
  1609.                 ++i;
  1610.             }
  1611.             if (!ok) {
  1612.                 Error(MyGetMsg(MSG_EWRR),MyGetMsg(MSG_OK),ifilename,HE_Write);
  1613.             }
  1614.             // Close file and clean up
  1615.             if (!Close(fh)) {
  1616.                 if (ok) {
  1617.                     Error(MyGetMsg(MSG_ECLOF),MyGetMsg(MSG_OK),ifilename,HE_Close);
  1618.                     ok = FALSE;
  1619.                 }
  1620.             }
  1621.         }
  1622.         else {
  1623.             Error(MyGetMsg(MSG_EOPF),MyGetMsg(MSG_OK),ifilename,HE_Open);
  1624.             ok = FALSE;
  1625.         }
  1626.         // Write Icon if required and none already exists
  1627.         if (ok) {
  1628.             if (CreateIcons) {
  1629.                 if (MyDiskObject = GetDiskObject(savedfilename)) {
  1630.                     FreeDiskObject(MyDiskObject);
  1631.                 }
  1632.                 else {
  1633.                     if ((MyDiskObject = GetDiskObject("ENV:TSMorph/def_points")) ||
  1634.                         (MyDiskObject = GetDiskObject("ENV:SYS/def_points")) ||
  1635.                          (MyDiskObject = GetDefDiskObject(WBPROJECT))) {
  1636.                         PutDiskObject(savedfilename,MyDiskObject);
  1637.                         FreeDiskObject(MyDiskObject);
  1638.                     }
  1639.                 }
  1640.             }
  1641.             Saved = TRUE;
  1642.         }
  1643.     }
  1644.     else {
  1645.         ok = FALSE;
  1646.     }
  1647.     return ok;
  1648. }
  1649.  
  1650. /* Set editing mode
  1651.  * This sets the window title, pointer, gadgets, menus etc.
  1652.  */
  1653. void
  1654. MySetMode(UWORD NewMode) {
  1655.     UWORD             oldpos;                // Pointer to unlink gadgets
  1656.     UWORD             menupos;                // menu pointer
  1657.     struct Gadget     *Gadget1    = NULL;    // Gadget to update
  1658.     ULONG                HNum;
  1659.     // Determine "current" menu and gadget
  1660.     switch(Mode) {
  1661.     case EDIT1:
  1662.         Gadget1 = &OneGadget;
  1663.         menupos = MI_EDITONE;
  1664.         break;
  1665.     case EDIT2:
  1666.         Gadget1 = &TwoGadget;
  1667.         menupos = MI_EDITTWO;
  1668.         break;
  1669.     case EDITREL:
  1670.          Gadget1 = &RelGadget;
  1671.         menupos = MI_EDITREL;
  1672.          break;
  1673.     case ADD:
  1674.         Gadget1 = &MyAddGadget;
  1675.         menupos = MI_ADD;
  1676.         break;
  1677.     case DELETE:
  1678.         Gadget1 = &DelGadget;
  1679.         menupos = MI_DELETE;
  1680.         break;
  1681.     case LINK1:
  1682.     case LINK2:
  1683.     case LINK2A:
  1684.         Gadget1 = &LinkGadget;
  1685.         menupos = MI_LINK;
  1686.         break;
  1687.     case UNLINK1:
  1688.     case UNLINK2:
  1689.     case UNLINK2A:
  1690.         Gadget1 = &UnlinkGadget;
  1691.         menupos = MI_UNLINK;
  1692.         break;
  1693.     case NONE:
  1694.         Gadget1 = &NoneGadget;
  1695.         menupos = MI_NONE;
  1696.         break;
  1697.     }
  1698.     // Unselect old gadget
  1699.     oldpos = RemoveGList(ControlWindow,Gadget1,1);
  1700.     Gadget1->Flags &= ~GFLG_SELECTED;
  1701.     AddGList(ControlWindow,Gadget1,oldpos,1,NULL);
  1702.     RefreshGList(Gadget1,ControlWindow,NULL,1);
  1703.     /* Remove menus and
  1704.      * Unselect old menu item
  1705.      * Actually unselects all (why?)
  1706.      */
  1707.     if (!EGS) {
  1708.         if (Pic1_Open) {
  1709.             ClearMenuStrip(Pic1.Win);
  1710.         }
  1711.         if (Pic2_Open) {
  1712.             ClearMenuStrip(Pic2.Win);
  1713.         }
  1714.     }
  1715.     ClearMenuStrip(ControlWindow);
  1716.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,0)))->Flags &= ~CHECKED;
  1717.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,1)))->Flags &= ~CHECKED;
  1718.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,2)))->Flags &= ~CHECKED;
  1719.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,3)))->Flags &= ~CHECKED;
  1720.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,4)))->Flags &= ~CHECKED;
  1721.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,5)))->Flags &= ~CHECKED;
  1722.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,6)))->Flags &= ~CHECKED;
  1723.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,7)))->Flags &= ~CHECKED;
  1724.     // Determine "new" title, gadget and menu
  1725.     switch (NewMode) {
  1726.     case EDIT1:
  1727.         SetWindowTitles(ControlWindow,MyGetMsg(MSG_1),(UBYTE *)-1);
  1728.         Gadget1 = &OneGadget;
  1729.         menupos = MI_EDITONE;
  1730.         HNum = H_EOne;
  1731.         break;
  1732.     case EDIT2:
  1733.         SetWindowTitles(ControlWindow,MyGetMsg(MSG_2),(UBYTE *)-1);
  1734.         Gadget1 = &TwoGadget;
  1735.         menupos = MI_EDITTWO;
  1736.         HNum = H_ETwo;
  1737.         break;
  1738.     case EDITREL:
  1739.         SetWindowTitles(ControlWindow,MyGetMsg(MSG_REL),(UBYTE *)-1);
  1740.          Gadget1 = &RelGadget;
  1741.         menupos = MI_EDITREL;
  1742.         HNum = H_ERel;
  1743.         break;
  1744.     case ADD:
  1745.         SetWindowTitles(ControlWindow,MyGetMsg(MSG_ADD),(UBYTE *)-1);
  1746.           Gadget1 = &MyAddGadget;
  1747.         menupos = MI_ADD;
  1748.         HNum = H_EAdd;
  1749.         break;
  1750.     case DELETE:
  1751.         SetWindowTitles(ControlWindow,MyGetMsg(MSG_DEL),(UBYTE *)-1);
  1752.           Gadget1 = &DelGadget;
  1753.         menupos = MI_DELETE;
  1754.         HNum = H_EDel;
  1755.         break;
  1756.     case LINK1:
  1757.         SetWindowTitles(ControlWindow,MyGetMsg(MSG_L1),(UBYTE *)-1);
  1758.           Gadget1 = &LinkGadget;
  1759.         menupos = MI_LINK;
  1760.         HNum = H_ELnk;
  1761.         break;
  1762.     case UNLINK1:
  1763.         SetWindowTitles(ControlWindow,MyGetMsg(MSG_U1),(UBYTE *)-1);
  1764.           Gadget1 = &UnlinkGadget;
  1765.         menupos = MI_UNLINK;
  1766.         HNum = H_EUnl;
  1767.         break;
  1768.     case NONE:
  1769.         SetWindowTitles(ControlWindow,MyGetMsg(MSG_MOV),(UBYTE *)-1);
  1770.          Gadget1 = &NoneGadget;
  1771.         menupos = MI_NONE;
  1772.         HNum = H_EMov;
  1773.         break;
  1774.     }
  1775.     // Select new gadget
  1776.     oldpos = RemoveGList(ControlWindow,Gadget1,1);
  1777.     Gadget1->Flags |= GFLG_SELECTED;
  1778.     AddGList(ControlWindow,Gadget1,oldpos,1,NULL);
  1779.     RefreshGList(Gadget1,ControlWindow,NULL,1);
  1780.     // Select new menu item and readd menus
  1781.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,menupos)))->Flags |= CHECKED;
  1782.     ResetMenuStrip(ControlWindow,MyMenu);
  1783.     if (!EGS) {
  1784.         if (Pic1_Open) {
  1785.             ResetMenuStrip(Pic1.Win,MyMenu);
  1786.         }
  1787.         if (Pic2_Open) {
  1788.             ResetMenuStrip(Pic2.Win,MyMenu);
  1789.         }
  1790.     }
  1791.     // Set mode and set the pointer
  1792.     Mode = NewMode;
  1793.     SetMyPointer();
  1794.     // Display (short) help
  1795.     if (GHelp) {
  1796.         help(HNum);
  1797.     }
  1798.     else {
  1799.         ihelp(HNum);
  1800.     }
  1801. }
  1802.  
  1803. BOOL                         SelDown = FALSE;    // Set if left button currently pressed
  1804. UWORD                     OldLeft,        // Old position of image
  1805.                             OldTop;
  1806. UWORD                     OldLeft1,    // Old position of other image
  1807.                             OldTop1;
  1808. struct MyPoint         *MyPoint,    // Points to add, link etc.
  1809.                             *MyPoint1;
  1810. SHORT                     OldX,            // Old coordinates
  1811.                             OldY;
  1812. SHORT                     OldX1,        // Old coordinates in other window
  1813.                             OldY1;
  1814. SHORT                     CurX,            // Current coordinates
  1815.                             CurY;
  1816. SHORT                     CurX1,        // Current coordinates in other window
  1817.                             CurY1;
  1818. struct Picture         *pic1;        // The other image
  1819.  
  1820. /* The main program
  1821.  * this loops until the program is quited
  1822.  */
  1823. void
  1824. doMsgLoop(void) {
  1825.     UWORD                     X,                // Coordinates
  1826.                                 Y;
  1827.     struct IntuiMessage     *msg;            // Message from the Control window
  1828.     struct EI_EIntuiMsg     *EGSmsg;        // Message from the EGS windows
  1829.     struct Picture         *pic;            // Main image pointer
  1830.     int                         flag     = 1;    // 1 = keep going, 0 = quit, 2 = Close control and image windows
  1831.     UWORD                     Shift;        // Set if either Shift key pressed
  1832.     ULONG                     Signals;        // Signals set after Wait()
  1833.     UWORD                     Selection;    // Menu selection
  1834.     struct AmigaGuideMsg *agm;            // message from amigaguide
  1835.     ULONG HNum;                                // The Help node to use
  1836.     /* Loop until we quit    */
  1837.     while (flag==1) {
  1838.         // Wait on open windows etc.
  1839.         Signals = Wait((ASig) |
  1840.                             (1L << TSMorphWnd->UserPort->mp_SigBit) |
  1841.                             (1L << WMsgPortp->mp_SigBit) |
  1842.                             (ControlWindow ? (1L << ControlWindow->UserPort->mp_SigBit) : 0));
  1843.         // Something for the Information window
  1844.         if (Signals & (1L << TSMorphWnd->UserPort->mp_SigBit)) {
  1845.             flag = HandleTSMorphIDCMP();
  1846.         }
  1847.         /* Something for amigaguide
  1848.          * Note: all we do is reply the message(s)
  1849.          */
  1850.         if (Signals & ASig) {
  1851.             if (handle) {
  1852.                 while (agm = GetAmigaGuideMsg(handle)) {
  1853.                     switch (agm->agm_Type) {
  1854.                     case ToolCmdReplyID:
  1855.                         break;
  1856.                     case ToolStatusID:
  1857.                         break;
  1858.                     default:
  1859.                         break;
  1860.                     }
  1861.                     ReplyAmigaGuideMsg(agm);
  1862.                 }
  1863.             }
  1864.         }
  1865.         // Something for the Control window
  1866.         if (ControlWindow &&
  1867.             (Signals & (1L << ControlWindow->UserPort->mp_SigBit))) {
  1868.             // Loop on all messages
  1869.              while (msg = (struct IntuiMessage *)GetMsg(ControlWindow->UserPort)) {
  1870.                  switch (msg->Class) {
  1871.                  // gadget help
  1872.                  case IDCMP_GADGETHELP:
  1873.                      if (msg->IAddress == NULL) {
  1874.                          HNum = 0;
  1875.                      }
  1876.                      else {
  1877.                          if (msg->IAddress == ControlWindow) {
  1878.                             switch(Mode) {
  1879.                             case EDIT1:
  1880.                                 HNum = H_EOne;
  1881.                                 break;
  1882.                             case EDIT2:
  1883.                                 HNum = H_ETwo;
  1884.                                 break;
  1885.                             case EDITREL:
  1886.                                 HNum = H_ERel;
  1887.                                  break;
  1888.                             case ADD:
  1889.                                 HNum = H_EAdd;
  1890.                                 break;
  1891.                             case DELETE:
  1892.                                 HNum = H_EDel;
  1893.                                 break;
  1894.                             case LINK1:
  1895.                             case LINK2:
  1896.                             case LINK2A:
  1897.                                 HNum = H_ELnk;
  1898.                                 break;
  1899.                             case UNLINK1:
  1900.                             case UNLINK2:
  1901.                             case UNLINK2A:
  1902.                                 HNum = H_EUnl;
  1903.                                 break;
  1904.                             case NONE:
  1905.                                 HNum = H_EMov;
  1906.                                 break;
  1907.                             default:
  1908.                                 HNum = H_CWindow;
  1909.                                 break;
  1910.                             }
  1911.                         }
  1912.                          else {
  1913.                              switch (((struct Gadget *)msg->IAddress)->GadgetType &0xf0) {
  1914.                              case GTYP_WDRAGGING:
  1915.                                  HNum = H_CWindow;
  1916.                                  break;
  1917.                              case GTYP_WUPFRONT:
  1918.                                  HNum = H_CDepth;
  1919.                                  break;
  1920.                              case GTYP_CLOSE:
  1921.                                  HNum = H_CClose;
  1922.                                  break;
  1923.                              case 0:
  1924.                                  switch (((struct Gadget *)msg->IAddress)->GadgetID) {
  1925.                                  case ONEGADGET:
  1926.                                      HNum = H_EOne;
  1927.                                      break;
  1928.                                  case TWOGADGET:
  1929.                                      HNum = H_ETwo;
  1930.                                      break;
  1931.                                  case RELGADGET:
  1932.                                      HNum = H_ERel;
  1933.                                      break;
  1934.                                  case DELGADGET:
  1935.                                      HNum = H_EDel;
  1936.                                      break;
  1937.                                  case UNLINKGADGET:
  1938.                                      HNum = H_EUnl;
  1939.                                      break;
  1940.                                  case LINKGADGET:
  1941.                                      HNum = H_ELnk;
  1942.                                      break;
  1943.                                  case NONEGADGET:
  1944.                                      HNum = H_EMov;
  1945.                                      break;
  1946.                                  case ADDGADGET:
  1947.                                      HNum = H_EAdd;
  1948.                                      break;
  1949.                                  case STGADGET:
  1950.                                      HNum = HC_First;
  1951.                                      break;
  1952.                                  case PREVGADGET:
  1953.                                      HNum = HC_Previous;
  1954.                                      break;
  1955.                                  case GOTOGADGET:
  1956.                                      HNum = HC_Goto;
  1957.                                      break;
  1958.                                  case NEXTGADGET:
  1959.                                      HNum = HC_Next;
  1960.                                      break;
  1961.                                  case LASTGADGET:
  1962.                                      HNum = HC_Last;
  1963.                                      break;
  1964.                                  default:
  1965.                                      HNum = H_CWindow;
  1966.                                      break;
  1967.                                  }
  1968.                                  break;
  1969.                              default:
  1970.                                  HNum = H_CWindow;
  1971.                                  break;
  1972.                              }
  1973.                          }
  1974.                      }
  1975.                      if (HNum) {
  1976.                          if (GHelp) {
  1977.                              help(HNum);
  1978.                          }
  1979.                          else {
  1980.                              ihelp(HNum);
  1981.                          }
  1982.                      }
  1983.                      break;
  1984.                  case IDCMP_VANILLAKEY:
  1985.                      // No vanilla keys currently defined
  1986.                      break;
  1987.                  case IDCMP_RAWKEY:
  1988.                      // only raw key is the help key
  1989.                      switch (msg->Code) {
  1990.                      case 0x5F:
  1991.                          /* determine if pointer is in a gadget
  1992.                           * otherwise show help on the whole window
  1993.                           */
  1994.                         X = ControlWindow->MouseX;
  1995.                         Y = ControlWindow->MouseY;
  1996.                         if (PointInBox(X,Y,0,0,
  1997.                                                 CLOSEIMAGE_W(n),ControlWindow->BorderTop))
  1998.                             HNum = H_CClose;
  1999.                         else
  2000.                         if (PointInBox(X,Y,(ControlWindow->Width - DEPTHIMAGE_W(n)),0,
  2001.                                                 ControlWindow->Width,ControlWindow->BorderTop))
  2002.                             HNum = H_CDepth;
  2003.                         else
  2004.                         if (PointInBox(X,Y,OneGadget.LeftEdge,OneGadget.TopEdge,
  2005.                                                 OneGadget.LeftEdge+OneGadget.Width,OneGadget.TopEdge+OneGadget.Height))
  2006.                             HNum = H_EOne;
  2007.                         else
  2008.                         if (PointInBox(X,Y,TwoGadget.LeftEdge,TwoGadget.TopEdge,
  2009.                                                 TwoGadget.LeftEdge+TwoGadget.Width,TwoGadget.TopEdge+TwoGadget.Height))
  2010.                             HNum = H_ETwo;
  2011.                         else
  2012.                         if (PointInBox(X,Y,RelGadget.LeftEdge,RelGadget.TopEdge,
  2013.                                                 RelGadget.LeftEdge+RelGadget.Width,RelGadget.TopEdge+RelGadget.Height))
  2014.                             HNum = H_ERel;
  2015.                         else
  2016.                         if (PointInBox(X,Y,DelGadget.LeftEdge,DelGadget.TopEdge,
  2017.                                                 DelGadget.LeftEdge+DelGadget.Width,DelGadget.TopEdge+DelGadget.Height))
  2018.                             HNum = H_EDel;
  2019.                         else
  2020.                         if (PointInBox(X,Y,UnlinkGadget.LeftEdge,UnlinkGadget.TopEdge,
  2021.                                                 UnlinkGadget.LeftEdge+UnlinkGadget.Width,UnlinkGadget.TopEdge+UnlinkGadget.Height))
  2022.                             HNum = H_EUnl;
  2023.                         else
  2024.                         if (PointInBox(X,Y,LinkGadget.LeftEdge,LinkGadget.TopEdge,
  2025.                                                 LinkGadget.LeftEdge+LinkGadget.Width,LinkGadget.TopEdge+LinkGadget.Height))
  2026.                             HNum = H_ELnk;
  2027.                         else
  2028.                         if (PointInBox(X,Y,NoneGadget.LeftEdge,NoneGadget.TopEdge,
  2029.                                                 NoneGadget.LeftEdge+NoneGadget.Width,NoneGadget.TopEdge+NoneGadget.Height))
  2030.                             HNum = H_EMov;
  2031.                         else
  2032.                         if (PointInBox(X,Y,MyAddGadget.LeftEdge,MyAddGadget.TopEdge,
  2033.                                                 MyAddGadget.LeftEdge+MyAddGadget.Width,MyAddGadget.TopEdge+MyAddGadget.Height))
  2034.                             HNum = H_EAdd;
  2035.                         else
  2036.                         if (PointInBox(X,Y,stGadget.LeftEdge,stGadget.TopEdge,
  2037.                                                 stGadget.LeftEdge+stGadget.Width,stGadget.TopEdge+stGadget.Height))
  2038.                             HNum = HC_First;
  2039.                         else
  2040.                         if (PointInBox(X,Y,prevGadget.LeftEdge,prevGadget.TopEdge,
  2041.                                                 prevGadget.LeftEdge+prevGadget.Width,prevGadget.TopEdge+prevGadget.Height))
  2042.                             HNum = HC_Previous;
  2043.                         else
  2044.                         if (PointInBox(X,Y,gotoGadget.LeftEdge,gotoGadget.TopEdge,
  2045.                                                 gotoGadget.LeftEdge+gotoGadget.Width,gotoGadget.TopEdge+gotoGadget.Height))
  2046.                             HNum = HC_Goto;
  2047.                         else
  2048.                         if (PointInBox(X,Y,nextGadget.LeftEdge,nextGadget.TopEdge,
  2049.                                                 nextGadget.LeftEdge+nextGadget.Width,nextGadget.TopEdge+nextGadget.Height))
  2050.                             HNum = HC_Next;
  2051.                         else
  2052.                         if (PointInBox(X,Y,lastGadget.LeftEdge,lastGadget.TopEdge,
  2053.                                                 lastGadget.LeftEdge+lastGadget.Width,lastGadget.TopEdge+lastGadget.Height))
  2054.                             HNum = HC_Last;
  2055.                         else
  2056.                             HNum = H_CWindow;
  2057.                         help(HNum);
  2058.                          break;
  2059.                      default:
  2060.                          // any other key
  2061.                          break;
  2062.                      }
  2063.                      break;
  2064.                  case IDCMP_MENUHELP:
  2065.                      // Show help on the Control and image windows menus
  2066.                      DoMenuHelp(msg->Code);
  2067.                      break;
  2068.                  case IDCMP_GADGETDOWN:
  2069.                      // Gadget down so set mode to the gadget pressed
  2070.                      switch (((struct Gadget *)(msg->IAddress))->GadgetID) {
  2071.                     case ONEGADGET:
  2072.                         MySetMode(EDIT1);
  2073.                          break;
  2074.                      case TWOGADGET:
  2075.                          MySetMode(EDIT2);
  2076.                           break;
  2077.                      case RELGADGET:
  2078.                           MySetMode(EDITREL);
  2079.                           break;
  2080.                      case ADDGADGET:
  2081.                          MySetMode(ADD);
  2082.                           break;
  2083.                      case DELGADGET:
  2084.                          MySetMode(DELETE);
  2085.                           break;
  2086.                       case LINKGADGET:
  2087.                           MySetMode(LINK1);
  2088.                           break;
  2089.                      case UNLINKGADGET:
  2090.                          MySetMode(UNLINK1);
  2091.                           break;
  2092.                       case NONEGADGET:
  2093.                           MySetMode(NONE);
  2094.                           break;
  2095.                       default:
  2096.                           // unkown gadget ?
  2097.                           break;
  2098.                      }
  2099.                      break;
  2100.                  case IDCMP_GADGETUP:
  2101.                      // Gadget up so change frame
  2102.                      switch (((struct Gadget *)(msg->IAddress))->GadgetID) {
  2103.                     case STGADGET:
  2104.                         flag = FirstFrame();
  2105.                          break;
  2106.                      case PREVGADGET:
  2107.                          flag = PrevFrame();
  2108.                          break;
  2109.                      case GOTOGADGET:
  2110.                          flag = GotoFrame();
  2111.                          break;
  2112.                      case NEXTGADGET:
  2113.                          flag = NextFrame();
  2114.                          break;
  2115.                      case LASTGADGET:
  2116.                          flag = LastFrame();
  2117.                          break;
  2118.                     default:
  2119.                         break;
  2120.                     }
  2121.                     break;
  2122.                  case IDCMP_CLOSEWINDOW:
  2123.                      // Close window - set flag to close image windows as well
  2124.                     flag = 2;
  2125.                      break;
  2126.                  case IDCMP_MENUPICK:
  2127.                      // Loop around menu selections
  2128.                     Selection = msg->Code;
  2129.                     while ((Selection != MENUNULL) && (flag==1)) {
  2130.                         flag = DoMenu(NULL,Selection);
  2131.                         Selection = ((struct MenuItem *)ItemAddress(MyMenu,(LONG)Selection))->NextSelect;
  2132.                     }
  2133.                      break;
  2134.                  default:
  2135.                      // unknown message
  2136.                      break;
  2137.                  }
  2138.                 ReplyMsg((struct Message *)msg);
  2139.              }
  2140.           }
  2141.           // Something from one of the image windows
  2142.         if (Signals & (1L << WMsgPortp->mp_SigBit)) {
  2143.          if (EGS) {
  2144.           while (EGSmsg = (struct EI_EIntuiMsg *)GetMsg(WMsgPortp)) {
  2145.             pic = (struct Picture *)(EGSmsg->IDCMPWindow->UserData);
  2146.            switch (EGSmsg->Class) {
  2147.            case EI_iNEWSIZE:
  2148.             // On resize reset EGS pointer (to prevent staying as arrow)
  2149.             SetMyPointer();
  2150.             break;
  2151.            case EI_iCLOSEWINDOW:
  2152.           flag = 2;
  2153.             break;
  2154.              case EI_iVANILLAKEY:
  2155.                  Vanilla(EGSmsg->Code);
  2156.                 break;
  2157.             case EI_iMOUSEBUTTONS:
  2158.                 MouseButtons(pic,EGSmsg->Code,EGSmsg->Seconds);
  2159.                 break;
  2160.             case EI_iMOUSEMOVE:
  2161.                 MouseMove(pic);
  2162.                 break;
  2163.             case EI_iACTIVEWINDOW:
  2164.                 /* Window became active
  2165.                  * Store time so that we can ignore the first click
  2166.                  * (for which we may next recieve a message)
  2167.                  * and change the screen palette (if required)
  2168.                  */
  2169.                 pic->JustSeconds = EGSmsg->Seconds;
  2170.                 break;
  2171.            default:
  2172.             break;
  2173.            }
  2174.            ReplyMsg((struct Message *)EGSmsg); 
  2175.           }
  2176.          }
  2177.          else {
  2178.           // Loop round messages
  2179.           while (msg = (struct IntuiMessage *)GetMsg(WMsgPortp)) {
  2180.              // determine which image it relates to
  2181.             pic = (struct Picture *)(msg->IDCMPWindow->UserData);
  2182.             switch (msg->Class) {
  2183.             case IDCMP_GADGETHELP:
  2184.                  if (msg->IAddress == NULL) {
  2185.                      HNum = 0;
  2186.                  }
  2187.                  else {
  2188.                      if (msg->IAddress == pic->Win) {
  2189.                         switch(Mode) {
  2190.                         case EDIT1:
  2191.                             HNum = H_EOne;
  2192.                             break;
  2193.                         case EDIT2:
  2194.                             HNum = H_ETwo;
  2195.                             break;
  2196.                         case EDITREL:
  2197.                             HNum = H_ERel;
  2198.                              break;
  2199.                         case ADD:
  2200.                             HNum = H_EAdd;
  2201.                             break;
  2202.                         case DELETE:
  2203.                             HNum = H_EDel;
  2204.                             break;
  2205.                         case LINK1:
  2206.                         case LINK2:
  2207.                         case LINK2A:
  2208.                             HNum = H_ELnk;
  2209.                             break;
  2210.                         case UNLINK1:
  2211.                         case UNLINK2:
  2212.                         case UNLINK2A:
  2213.                             HNum = H_EUnl;
  2214.                             break;
  2215.                         case NONE:
  2216.                             HNum = H_EMov;
  2217.                             break;
  2218.                         default:
  2219.                             HNum = H_EWindow;
  2220.                             break;
  2221.                         }
  2222.                      }
  2223.                      else {
  2224.                          switch (((struct Gadget *)msg->IAddress)->GadgetType &0xf0) {
  2225.                          case GTYP_SIZING:
  2226.                              HNum = H_ESize;
  2227.                              break;
  2228.                          case GTYP_WDRAGGING:
  2229.                              HNum = H_EWindow;
  2230.                              break;
  2231.                          case GTYP_WUPFRONT:
  2232.                              HNum = H_EDepth;
  2233.                              break;
  2234.                          case GTYP_WDOWNBACK:
  2235.                              HNum = H_EZoom;
  2236.                              break;
  2237.                          case GTYP_CLOSE:
  2238.                              HNum = H_EClose;
  2239.                              break;
  2240.                          case 0:
  2241.                              switch (((struct Gadget *)msg->IAddress)->GadgetID) {
  2242.                              case LEFT_RIGHT_GADGET:
  2243.                                  HNum = H_Horiz;
  2244.                                  break;
  2245.                              case UP_DOWN_GADGET:
  2246.                                  HNum = H_Vert;
  2247.                                  break;
  2248.                              case UP_GADGET:
  2249.                                  HNum = H_Up;
  2250.                                  break;
  2251.                              case DOWN_GADGET:
  2252.                                  HNum = H_Down;
  2253.                                  break;
  2254.                              case LEFT_GADGET:
  2255.                                  HNum = H_Left;
  2256.                                  break;
  2257.                              case RIGHT_GADGET:
  2258.                                  HNum = H_Right;
  2259.                                  break;
  2260.                              default:
  2261.                                  HNum = H_EWindow;
  2262.                                  break;
  2263.                              }
  2264.                              break;
  2265.                          default:
  2266.                              HNum = H_EWindow;
  2267.                              break;
  2268.                          }
  2269.                      }
  2270.                  }
  2271.                  if (HNum) {
  2272.                      if (GHelp) {
  2273.                          help(HNum);
  2274.                      }
  2275.                      else {
  2276.                          ihelp(HNum);
  2277.                      }
  2278.                  }
  2279.                 break;
  2280.             case IDCMP_NEWSIZE:
  2281.                 // Image resized so resize the gadgets etc.
  2282.                 pic->JustSeconds = 0;    // Note No break !!!!!!!
  2283.             case IDCMP_CHANGEWINDOW:
  2284.                 /* reset window size after change in Zoom
  2285.                  * Changing from 2x to normal size may require the windows
  2286.                  * to be made smaller - this can be delayed by intuition.
  2287.                  * The window limits can only be reset when the window has
  2288.                  * been actually resized.
  2289.                  */
  2290.                 if (ZoomAllowed && !Zoom) {
  2291.                     if (changedboxcount < 3) {
  2292.                         if (WindowLimits(pic->Win,0,0,pic->ilbm->Bmhd.w+pic->Screen->WBorLeft+SIZEIMAGE_W(n),
  2293.                                         pic->ilbm->Bmhd.h+pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n))) {
  2294.                             if (pic == &Pic1) {
  2295.                                 changedboxcount |= 1;
  2296.                             }
  2297.                             else {
  2298.                                 if (pic == &Pic2) {
  2299.                                     changedboxcount |= 2;
  2300.                                 }
  2301.                             }
  2302.                             if (changedboxcount == 3) {
  2303.                                 /* Once both windows have been resized then we
  2304.                                  * can redraw all the points
  2305.                                  */
  2306.                                 DrawAllPoints();
  2307.                             }
  2308.                         }
  2309.                         else {
  2310.                             /* User must have resized in the meantime
  2311.                              * so have another go
  2312.                              */
  2313.                             ChangeWindowBox(pic->Win,pic->Win->LeftEdge,pic->Win->TopEdge,
  2314.                                          min(pic->Win->Width,pic->ilbm->Bmhd.w+pic->Screen->WBorLeft+SIZEIMAGE_W(n)),
  2315.                                          min(pic->Win->Height,pic->ilbm->Bmhd.h+pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n)));
  2316.                         }
  2317.                     }
  2318.                 }
  2319.                 // Reset gadgets etc. for new size
  2320.                 doNewSize(pic);
  2321.                 break;
  2322.              case IDCMP_VANILLAKEY:
  2323.                  Vanilla(msg->Code);
  2324.                 break;
  2325.               case IDCMP_RAWKEY:
  2326.                   // Only raw key currently used is the help key
  2327.                   switch (msg->Code) {
  2328.                  case 0x5F:
  2329.                      /* Determine the gadget the pointer is over
  2330.                       * or show help on the whole window
  2331.                       */
  2332.                     X = msg->IDCMPWindow->MouseX;
  2333.                     Y = msg->IDCMPWindow->MouseY;
  2334.                     if (PointInBox(X,Y,0,0,
  2335.                                             CLOSEIMAGE_W(n),msg->IDCMPWindow->BorderTop))
  2336.                         HNum = H_EClose;
  2337.                     else
  2338.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width - DEPTHIMAGE_W(n)),0,
  2339.                                             msg->IDCMPWindow->Width,msg->IDCMPWindow->BorderTop))
  2340.                         HNum = H_EDepth;
  2341.                     else
  2342.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width - DEPTHIMAGE_W(n) - ZOOMIMAGE_W(n)),0,
  2343.                                             (msg->IDCMPWindow->Width - DEPTHIMAGE_W(n)),msg->IDCMPWindow->BorderTop))
  2344.                         HNum = H_EZoom;
  2345.                     else
  2346.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width - SIZEIMAGE_W(n)),(msg->IDCMPWindow->Height-10),
  2347.                                             msg->IDCMPWindow->Width,msg->IDCMPWindow->Height))
  2348.                         HNum = H_ESize;
  2349.                     else
  2350.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-LEFTIMAGE_W(n)-RIGHTIMAGE_W(n)),(msg->IDCMPWindow->Height-LEFTIMAGE_H(n)),
  2351.                                             (msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-RIGHTIMAGE_W(n)),msg->IDCMPWindow->Height))
  2352.                         HNum = H_Left;
  2353.                     else
  2354.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-RIGHTIMAGE_W(n)),(msg->IDCMPWindow->Height-RIGHTIMAGE_H(n)),
  2355.                                             (msg->IDCMPWindow->Width-SIZEIMAGE_W(n)),msg->IDCMPWindow->Height))
  2356.                         HNum = H_Right;
  2357.                     else
  2358.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-UPIMAGE_W(n)),(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n)-UPIMAGE_H(n)),
  2359.                                             msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n))))
  2360.                         HNum = H_Up;
  2361.                     else
  2362.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-UPIMAGE_W(n)),(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n)),
  2363.                                             msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n))))
  2364.                         HNum = H_Down;
  2365.                     else
  2366.                     if (PointInBox(X,Y,0,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)),
  2367.                                             (msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-LEFTIMAGE_W(n)-RIGHTIMAGE_W(n)),msg->IDCMPWindow->Height))
  2368.                         HNum = H_Horiz;
  2369.                     else
  2370.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)),msg->IDCMPWindow->BorderTop,
  2371.                                             msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-UPIMAGE_H(n)-DOWNIMAGE_H(n))))
  2372.                         HNum = H_Vert;
  2373.                     else
  2374.                         HNum = H_EWindow;
  2375.                     help(HNum);
  2376.                       break;
  2377.                   default:
  2378.                       // some other key
  2379.                       break;
  2380.                   }
  2381.                   break;
  2382.               case IDCMP_MENUHELP:
  2383.                   // Display help on Control and Image window menus
  2384.                   DoMenuHelp(msg->Code);
  2385.                   break;
  2386.             case IDCMP_ACTIVEWINDOW:
  2387.                 /* Window became active
  2388.                  * Store time so that we can ignore the first click
  2389.                  * (for which we may next recieve a message)
  2390.                  * and change the screen palette (if required)
  2391.                  */
  2392.                 pic->JustSeconds = msg->Seconds;
  2393.                 if (flag == 1) {
  2394.                     ColorWindow(pic);
  2395.                 }
  2396.                 break;
  2397.             case IDCMP_INACTIVEWINDOW:
  2398.                 /* Window just became inactive
  2399.                  * change the screen palette back if required
  2400.                  */
  2401.                 UnColorWindow(pic);
  2402.                 break;
  2403.             case IDCMP_MENUVERIFY:
  2404.                 /* Somebody wants to display a menu
  2405.                  * If it is somebody else then just let them
  2406.                  * otherwise if the left mouse button is down then
  2407.                  * do not display the menu as we are going to use
  2408.                  * the right button up/down message to cancel the current action
  2409.                  * otherwise change the screen palette back if required
  2410.                  * so that our menus can be readably displayed
  2411.                  */
  2412.                 switch (msg->Code) {
  2413.                 case MENUWAITING:
  2414.                     break;
  2415.                 case MENUHOT:
  2416.                     pic->JustSeconds = 0;
  2417.                     if (SelDown) {
  2418.                         msg->Code = MENUCANCEL;
  2419.                     }
  2420.                     else {
  2421.                         UnColorWindow(pic);
  2422.                     }
  2423.                     break;
  2424.                 default:
  2425.                     break;
  2426.                 }
  2427.                 break;
  2428.               case IDCMP_MENUPICK:
  2429.                   // Menu item selected, use any further clicks and loop round menu selections
  2430.                 pic->JustSeconds = 0;
  2431.                 Selection = msg->Code;
  2432.                 while ((Selection != MENUNULL) && flag) {
  2433.                     flag = DoMenu(pic,Selection);
  2434.                     Selection = ((struct MenuItem *)ItemAddress(MyMenu,(LONG)Selection))->NextSelect;
  2435.                  }
  2436.                  /* If we are changing palettes and quit
  2437.                   * was not just selected then change
  2438.                   * palette back to the image palette
  2439.                   * after a menu selections
  2440.                   */
  2441.                 if (palette && pic && (flag==1)) {
  2442.                     ColorWindow(pic);
  2443.                 }
  2444.                 break;
  2445.              case IDCMP_CLOSEWINDOW:
  2446.                  /* Close the window with Control and other image windows
  2447.                   * and change the palette back to original if required
  2448.                   */
  2449.                  UnColorWindow(pic);
  2450.                 flag = 2;
  2451.                   break;
  2452.             case IDCMP_MOUSEBUTTONS:
  2453.                 MouseButtons(pic,msg->Code,msg->Seconds);
  2454.                 break;
  2455.             case IDCMP_MOUSEMOVE:
  2456.                 MouseMove(pic);
  2457.                 break;
  2458.             case IDCMP_GADGETDOWN:
  2459.                 // Gadget down, save the current gadget id
  2460.                 pic->JustSeconds = 0;
  2461.                 pic->currentg = ((struct Gadget *)(msg->IAddress))->GadgetID;
  2462.                 break;
  2463.             case IDCMP_GADGETUP:
  2464.                 // Gadget up, no current gadget id
  2465.                 pic->JustSeconds = 0;
  2466.                 pic->currentg = NO_GADGET;
  2467.                 break;
  2468.             case IDCMP_IDCMPUPDATE:
  2469.                 // Gadget update message
  2470.                 pic->JustSeconds = 0;
  2471.                 /* If an arrow then check the mouse button
  2472.                  * is down (prevents image scrolling long
  2473.                  * after button is released)
  2474.                  */
  2475.                 if ((pic->currentg == LEFT_RIGHT_GADGET) ||
  2476.                      (pic->currentg == UP_DOWN_GADGET) ||
  2477.                      (PeekQualifier() & IEQUALIFIER_LEFTBUTTON)) {
  2478.                     pic->XLeft=pic->Left;
  2479.                     pic->XTop=pic->Top;
  2480.                     Shift = PeekQualifier() & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT);
  2481.                     switch(pic->currentg) {
  2482.                     case LEFT_RIGHT_GADGET:
  2483.                         // Horizontal gadget - get position
  2484.                         pic->Left = msg->Code;
  2485.                         break;
  2486.                     case UP_DOWN_GADGET:
  2487.                         // Vertical gadget - get position
  2488.                         pic->Top = msg->Code;
  2489.                         break;
  2490.                     case UP_GADGET:
  2491.                         // Up gadget, check shift key
  2492.                         if (pic->Top) {
  2493.                             if (Shift)
  2494.                                 --(pic->Top);
  2495.                             else
  2496.                             if (pic->Top > pic->ATop)
  2497.                                     pic->Top -= pic->ATop;
  2498.                                 else
  2499.                                     pic->Top = 0;
  2500.                             SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  2501.                                 PGA_Top, pic->Top, TAG_END);
  2502.                         }
  2503.                         break;
  2504.                     case LEFT_GADGET:
  2505.                         // Left gadget, check shift key
  2506.                         if (pic->Left) {
  2507.                             if (Shift)
  2508.                                 --(pic->Left);
  2509.                             else
  2510.                                 if (pic->Left > pic->ALeft)
  2511.                                     pic->Left -= pic->ALeft;
  2512.                                 else
  2513.                                     pic->Left = 0;
  2514.                             SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  2515.                                 PGA_Top, pic->Left, TAG_END);
  2516.                         }
  2517.                         break;
  2518.                     case DOWN_GADGET:
  2519.                         // Down gadget, check shift key
  2520.                         if (Shift)
  2521.                             ++(pic->Top);
  2522.                         else
  2523.                             pic->Top += pic->ATop;
  2524.                         if (pic->Top > pic->MTop)
  2525.                             pic->Top = pic->MTop;
  2526.                         SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  2527.                             PGA_Top, pic->Top, TAG_END);
  2528.                         break;
  2529.                     case RIGHT_GADGET:
  2530.                         // Right gadget, check shift key
  2531.                         if (Shift)
  2532.                             ++(pic->Left);
  2533.                         else
  2534.                             pic->Left += pic->ALeft;
  2535.                         if (pic->Left > pic->MLeft)
  2536.                             pic->Left = pic->MLeft;
  2537.                         SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  2538.                             PGA_Top, pic->Left, TAG_END);
  2539.                         break;
  2540.                     }
  2541.                     // Update image scroll
  2542.                     checkGadget(pic); 
  2543.                     break;
  2544.                 }
  2545.             }
  2546.             ReplyMsg((struct Message *)msg);
  2547.           }
  2548.          }
  2549.         }
  2550.         /* If a window was closed etc.
  2551.          * then turn on some menus and close the windows
  2552.          * etc.
  2553.          */
  2554.         if ((flag == 2) || (flag == 3)) {
  2555.             if ((flag == 2) &&
  2556.                  ((SinglePicture == 2) || (SinglePicture == 3))) {
  2557.                 if (!Saved) {
  2558.                     flag = SaveRequester();
  2559.                 }
  2560.                 DeleteAllPoints();
  2561.             }
  2562.             if (flag) {
  2563.                 OnMenu(TSMorphWnd,FULLMENUNUM(0,0,NOSUB));
  2564.                 OnMenu(TSMorphWnd,FULLMENUNUM(0,1,NOSUB));
  2565.                 if (Pic1_Open) {
  2566.                     CloseAPicture(&Pic1);
  2567.                     Pic1_Open = FALSE;
  2568.                 }
  2569.                 if (Pic2_Open) {
  2570.                     CloseAPicture(&Pic2);
  2571.                     Pic2_Open = FALSE;
  2572.                 }
  2573.                 if (EGS) {
  2574.                  E_ActivateAmigaScreen();
  2575.                  ScreenToFront(Scr);
  2576.                 }
  2577.                 CloseControlWindow();
  2578.             }
  2579.             // Below just updates the correct gadgets
  2580.             EnableWindows();
  2581.              flag = 1;
  2582.         }
  2583.     }
  2584. }
  2585.  
  2586. //struct E_EMouse EGS_Pointer = {0x00000001, 0xFF0000FF, 0x80000080,
  2587. //struct E_EMouse EGS_Pointer = {0x00000000, 0xFF000000, 0xFFFFFF00,
  2588. //                                            1,1,32,32,NULL,NULL };
  2589. //ULONG EGS_Soft[32][2] = {0};    // Should be E_SoftMouse but that is LONG!
  2590. // Fix for 3.1 EGS includes 2.2
  2591. struct E_EMouseImg32 EMouseImg = {32,32,1,1};
  2592. struct E_EMouse EGS_Pointer = {0x00000000, 0xFF000000, 0xFFFFFF00,
  2593.                                          EMSF_HALF32,
  2594.                                          EMSV_01,NULL,&EMouseImg,NULL};
  2595.  
  2596. /* SetPointer
  2597.  * based on the current mode
  2598.  */
  2599. void
  2600. SetMyPointer(void) {
  2601.     UWORD *Pointer;    // Pointer image
  2602.     int i,j;
  2603.     UWORD a,b;
  2604.     ULONG c,d;
  2605.     // Set pointer based on mode
  2606.     switch (Mode) {
  2607.     case EDIT1:
  2608.         Pointer = One;
  2609.          break;
  2610.     case EDIT2:
  2611.         Pointer = Two;
  2612.         break;
  2613.     case EDITREL:
  2614.         Pointer = Rel;
  2615.         break;
  2616.     case ADD:
  2617.         Pointer = Add;
  2618.         break;
  2619.     case DELETE:
  2620.         Pointer = Del;
  2621.         break;
  2622.     case LINK1:
  2623.         Pointer = L1;
  2624.         break;
  2625.     case UNLINK1:
  2626.         Pointer = U1;
  2627.         break;
  2628.     case NONE:
  2629.         Pointer = Mov;
  2630.         break;
  2631.     case UNLINK2:
  2632.         Pointer = U2;
  2633.         break;
  2634.     case LINK2:
  2635.         Pointer = L2;
  2636.         break;
  2637.     }
  2638.     if (EGS) {
  2639.         // Convert intuition pointer to EGS pointer
  2640.         for (i = 0; i < 16; i++) {
  2641.             a = Pointer[(i<<1)+2];
  2642.             b = Pointer[(i<<1)+3];
  2643.             c = 0;
  2644.             for (j = 0; j < 8; j++) {
  2645.                 if ((a & 0x8000) && (b & 0x8000)) {
  2646.                     c |= 15;
  2647.                 }
  2648.                 else {
  2649.                     if (b & 0x8000) {
  2650.                         c |= 0x10;
  2651.                     }
  2652.                     else {
  2653.                         if (a & 0x8000) {
  2654.                             c |= 0x5;
  2655.                         }
  2656.                     }
  2657.                 }
  2658.                 a <<= 1;
  2659.                 b <<= 1;
  2660.                 if (j < 7) {
  2661.                     c <<= 4;
  2662.                 }
  2663.             }
  2664.             d = 0;
  2665.             for (j = 0; j < 8; j++) {
  2666.                 if ((a & 0x8000) && (b & 0x8000)) {
  2667.                     d |= 15;
  2668.                 }
  2669.                 else {
  2670.                     if (b & 0x8000) {
  2671.                         d |= 0x10;
  2672.                     }
  2673.                     else {
  2674.                         if (a & 0x8000) {
  2675.                             d |= 0x5;
  2676.                         }
  2677.                     }
  2678.                 }
  2679.                 a <<= 1;
  2680.                 b <<= 1;
  2681.                 if (j < 7) {
  2682.                     d <<= 4;
  2683.                 }
  2684.             }
  2685. //            EGS_Soft[i<<1][0] = c;
  2686. //            EGS_Soft[i<<1][1] = d;
  2687. //            EGS_Soft[(i<<1)+1][0] = c;
  2688. //            EGS_Soft[(i<<1)+1][1] = d;
  2689.             EMouseImg.image[i<<1][0] = c;
  2690.             EMouseImg.image[i<<1][1] = d;
  2691.             EMouseImg.image[(i<<1)+1][0] = c;
  2692.             EMouseImg.image[(i<<1)+1][1] = d;
  2693.         }
  2694. //        EGS_Pointer.Soft = &EGS_Soft;
  2695.     }
  2696.     // Set the window pointers
  2697.     if (Pic1_Open) {
  2698.         if (!EGS) {
  2699.             SetPointer(Pic1.Win, Pointer, 16, 16, -1, 0);
  2700.         }
  2701.         else {
  2702.             EI_ClearPointer(Pic1.EGS_Win);
  2703.             EI_SetPointer(Pic1.EGS_Win,&EGS_Pointer);
  2704.         }
  2705.     }
  2706.     if (Pic2_Open) {
  2707.         if (!EGS) {
  2708.             SetPointer(Pic2.Win, Pointer, 16, 16, -1, 0);
  2709.         }
  2710.         else {
  2711.             EI_ClearPointer(Pic2.EGS_Win);
  2712.             EI_SetPointer(Pic2.EGS_Win,&EGS_Pointer);
  2713.         }
  2714.     }
  2715.     if (ControlWindow) {
  2716.         SetPointer(ControlWindow, Pointer, 16, 16, -1, 0);
  2717.     }
  2718. }
  2719.  
  2720. /* Do the Control and image window menus
  2721.  * Returns    : 1 = OK, 0 = quit, 2=exit points
  2722.  * pic        : Picture structure if an image window
  2723.  * Selection: Menu item
  2724.  */
  2725. int
  2726. DoMenu(struct Picture *pic,UWORD Selection) {
  2727.     int flag = 1;            // Return value
  2728.     // Large switch statements for menu items
  2729.       switch (MENUNUM(Selection)) {
  2730.       case M_PROJECT:
  2731.         switch(ITEMNUM(Selection)) {
  2732.         case MM_NEW:
  2733.             /* New Points
  2734.              * Suggest Save if not saved
  2735.              * then delete all point
  2736.              */
  2737.             DisableWindows(DI_New);
  2738.             if (!Saved) {
  2739.                 if (SaveRequester()) {
  2740.                     Saved = TRUE;
  2741.                 }
  2742.             }
  2743.             if (Saved) {
  2744.                 DeleteAllPoints();
  2745.                 MaxWidth = 0;
  2746.                 MaxHeight = 0;
  2747.                 Saved = FALSE;
  2748.             }
  2749.             EnableWindows();
  2750.             break;
  2751.         case MM_OPEN:
  2752.             // Open Points - just call MyOpen() with JustPoints=TRUE
  2753.             DisableWindows(DI_WaitOpen);
  2754.             MyOpen(NULL,TRUE,TRUE);
  2755.             EnableWindows();
  2756.             break;
  2757.         case MM_SAVE:
  2758.             // Save - just call SaveAs() with last filename
  2759.             DisableWindows(DI_WaitSave);
  2760.             SaveAs(savedfilename);
  2761.             EnableWindows();
  2762.             break;
  2763.         case MM_SAVEAS:
  2764.             // Save - just call SaveAs() with no filename
  2765.             DisableWindows(DI_WaitSave);
  2766.             SaveAs(NULL);
  2767.             EnableWindows();
  2768.             break;
  2769.           case MM_ABOUT:
  2770.               // About - display requester
  2771.             DisableWindows(DI_About);
  2772.             About();
  2773.             EnableWindows();
  2774.             break;
  2775.         case MM_EXITPOINTS:
  2776.             // Exit Points - Close Image and control windows
  2777.             flag = 2;
  2778.             break;
  2779.         case MM_QUIT:
  2780.             // Quit - Suggest save first
  2781.             if (!Saved) {
  2782.                   flag = !SaveRequester();
  2783.               }
  2784.               else {
  2785.                   flag = 0;
  2786.               }
  2787.             break;
  2788.         case MM_PPREVIEW:
  2789.             Preview();
  2790.             break;
  2791.          default:
  2792.              // Some other item
  2793.               break;
  2794.         }
  2795.         break;
  2796.     case M_EDIT:
  2797.         switch(ITEMNUM(Selection)) {
  2798.         case MM_GRID:
  2799.             // Add Grid... - Add a grid of points
  2800.             AddGrid();
  2801.             break;
  2802.         case MM_TRIANGULATE:
  2803.             Triangulate();
  2804.             break;
  2805.         case MM_FRAME:
  2806.             // Frame sub menu
  2807.             switch (SUBNUM(Selection)) {
  2808.             case MI_FIRST:
  2809.                 flag = FirstFrame();
  2810.                 break;
  2811.             case MI_PREV:
  2812.                 flag = PrevFrame();
  2813.                 break;
  2814.             case MI_GOTO:
  2815.                 flag = GotoFrame();
  2816.                 break;
  2817.             case MI_NEXT:
  2818.                 flag = NextFrame();
  2819.                 break;
  2820.             case MI_LAST:
  2821.                 flag = LastFrame();
  2822.                 break;
  2823.             default:
  2824.                 break;
  2825.             }
  2826.             break;
  2827.         case MM_MODE:
  2828.             switch (SUBNUM(Selection)) {
  2829.             // Edit Mode ???? - set the relevant mode
  2830.               case MI_EDITONE:
  2831.                   MySetMode(EDIT1);
  2832.                   break;
  2833.              case MI_EDITTWO:
  2834.                   MySetMode(EDIT2);
  2835.                   break;
  2836.             case MI_EDITREL:
  2837.                 MySetMode(EDITREL);
  2838.                   break;
  2839.             case MI_ADD:
  2840.                 MySetMode(ADD);
  2841.                   break;
  2842.             case MI_DELETE:
  2843.                 MySetMode(DELETE);
  2844.                   break;
  2845.             case MI_LINK:
  2846.                 MySetMode(LINK1);
  2847.                   break;
  2848.             case MI_UNLINK:
  2849.                 MySetMode(UNLINK1);
  2850.                   break;
  2851.             case MI_NONE:
  2852.                 MySetMode(NONE);
  2853.                 break;
  2854.             default:
  2855.                 break;
  2856.             }
  2857.             break;
  2858.         default:
  2859.             // Some other item
  2860.             break;
  2861.         }
  2862.         break;
  2863.     case M_SETTINGS:
  2864.         HandleSettings(Selection,pic);
  2865.         break;
  2866.     default:
  2867.         // something else ??
  2868.         break;
  2869.     }
  2870.     // return 0,1 or 2
  2871.     return flag;
  2872. }
  2873.  
  2874. /* Disable all windows,
  2875.  * menus, pointers,
  2876.  * gadgets etc.
  2877.  *
  2878.  * Note: This must be able to be called multiple times without EnableWindows()
  2879.  */
  2880. void
  2881. DisableWindows(ULONG dnum) {
  2882.     if (dnum < 1000) {
  2883.         ihelp(dnum);
  2884.     }
  2885.     else {
  2886.         if (*(disabled[dnum-1000])) {
  2887.             if (Scr) {        // Need to check as TSMorphWnd is also used for backdrop temp window
  2888.                 if (TSMorphWnd) {
  2889.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_Help],TSMorphWnd,NULL,
  2890.                                         GTTX_Text,disabled[dnum-1000], TAG_END );
  2891.                 }
  2892.             }
  2893.         }
  2894.     }
  2895.     if (ControlWindow) {
  2896.         // All 3 menus off
  2897.         OffMenu(ControlWindow,FULLMENUNUM(M_PROJECT,NOITEM,NOSUB));
  2898.         OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,NOITEM,NOSUB));
  2899.         OffMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,NOITEM,NOSUB));
  2900.         // All gadgets off
  2901.         OffGadget(&OneGadget,ControlWindow,NULL);
  2902.         OffGadget(&TwoGadget,ControlWindow,NULL);
  2903.         OffGadget(&RelGadget,ControlWindow,NULL);
  2904.         OffGadget(&MyAddGadget,ControlWindow,NULL);
  2905.         OffGadget(&DelGadget,ControlWindow,NULL);
  2906.         OffGadget(&LinkGadget,ControlWindow,NULL);
  2907.         OffGadget(&UnlinkGadget,ControlWindow,NULL);
  2908.         OffGadget(&NoneGadget,ControlWindow,NULL);
  2909.         OffGadget(&stGadget,ControlWindow,NULL);
  2910.         OffGadget(&prevGadget,ControlWindow,NULL);
  2911.         OffGadget(&gotoGadget,ControlWindow,NULL);
  2912.         OffGadget(&nextGadget,ControlWindow,NULL);
  2913.         OffGadget(&lastGadget,ControlWindow,NULL);
  2914.         // Wait pointer
  2915.         SetPointer(ControlWindow, BusyPointerData, 16, 16, -6, 0);
  2916.     }
  2917.     if (Pic1_Open) {
  2918.      if (!EGS) {
  2919.         // Turn verify off
  2920.         IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  2921.                          IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  2922.                          IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  2923.                          IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  2924.                          IDCMP_GADGETHELP | IDCMP_MOUSEMOVE;
  2925.         ModifyIDCMP(Pic1.Win,IDCMPFlags);
  2926.         Pic1.Win->Flags |= WFLG_REPORTMOUSE;
  2927.         // All 3 menus off
  2928. //        OffMenu(Pic1.Win,FULLMENUNUM(0,NOITEM,NOSUB));    // These are now shared menus
  2929. //        OffMenu(Pic1.Win,FULLMENUNUM(1,NOITEM,NOSUB));
  2930. //        OffMenu(Pic1.Win,FULLMENUNUM(2,NOITEM,NOSUB));
  2931.         // Wait pointer
  2932.         SetPointer(Pic1.Win, BusyPointerData, 16, 16, -6, 0);
  2933.         // all gadgets off
  2934.         SetGadgetAttrs(Pic1.Lgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  2935.         SetGadgetAttrs(Pic1.Ugad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  2936.         SetGadgetAttrs(Pic1.Dgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  2937.         SetGadgetAttrs(Pic1.Rgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  2938.         SetGadgetAttrs(Pic1.SideGad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  2939.         SetGadgetAttrs(Pic1.BotGad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  2940.         RefreshGadgets(Pic1.BotGad,Pic1.Win,NULL);
  2941.      }
  2942.      else {
  2943.       EI_ClearPointer(Pic1.EGS_Win);
  2944.       EI_SetPointer(Pic1.EGS_Win,EI_GetPrefPointer(EIM_SLEEP_MOUSE));
  2945.      }
  2946.     }
  2947.     if (Pic2_Open) {
  2948.      if (!EGS) {
  2949.         // Turn verify off
  2950.         IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  2951.                          IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  2952.                          IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  2953.                          IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  2954.                          IDCMP_GADGETHELP | IDCMP_MOUSEMOVE;
  2955.         ModifyIDCMP(Pic2.Win,IDCMPFlags);
  2956.         Pic2.Win->Flags |= WFLG_REPORTMOUSE;
  2957.         // All 3 menus off
  2958. //        OffMenu(Pic2.Win,FULLMENUNUM(0,NOITEM,NOSUB));    // These are now shared menus
  2959. //        OffMenu(Pic2.Win,FULLMENUNUM(1,NOITEM,NOSUB));
  2960. //        OffMenu(Pic2.Win,FULLMENUNUM(2,NOITEM,NOSUB));
  2961.         // Wait pointer
  2962.         SetPointer(Pic2.Win, BusyPointerData, 16, 16, -6, 0);
  2963.         // all gadgets off
  2964.         SetGadgetAttrs(Pic2.Lgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  2965.         SetGadgetAttrs(Pic2.Ugad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  2966.         SetGadgetAttrs(Pic2.Dgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  2967.         SetGadgetAttrs(Pic2.Rgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  2968.         SetGadgetAttrs(Pic2.SideGad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  2969.         SetGadgetAttrs(Pic2.BotGad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  2970.         RefreshGadgets(Pic2.BotGad,Pic2.Win,NULL);
  2971.      }
  2972.      else {
  2973.       EI_ClearPointer(Pic2.EGS_Win);
  2974.       EI_SetPointer(Pic2.EGS_Win,EI_GetPrefPointer(EIM_SLEEP_MOUSE));
  2975.      }
  2976.     }
  2977.     /* Disable gadgets in the Info window
  2978.      * Do not disable the GetFile gadgets
  2979.      * as it causes enforcer hits
  2980.      */
  2981.     if (Scr) {
  2982.         if (TSMorphWnd) {
  2983.         //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile1],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);    // GetFile gadgets do not like being disabled
  2984.         //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile2],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2985.         //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileOne],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2986.         //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileTwo],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2987.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_EditPoints],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2988.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2989.         //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetSaveName],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2990.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2991.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2992.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2993.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2994.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2995.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2996.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  2997.             // Both menus off
  2998.             OffMenu(TSMorphWnd,FULLMENUNUM(0,NOITEM,NOSUB));
  2999.             OffMenu(TSMorphWnd,FULLMENUNUM(1,NOITEM,NOSUB));
  3000.             // Wait pointer
  3001.             SetPointer(TSMorphWnd, BusyPointerData, 16, 16, -6, 0);
  3002.         }
  3003.     }
  3004. }
  3005.  
  3006. /* Enable all windows,
  3007.  * menus, pointers,
  3008.  * gadgets etc.
  3009.  */
  3010. void
  3011. EnableWindows(void) {
  3012.     LONG Frames,Start;
  3013.     if (Scr) {
  3014.         if (TSMorphWnd) {
  3015.             Frames = GetNumber(TSMorphGadgets[GDX_Frames]);
  3016.             Start = GetNumber(TSMorphGadgets[GDX_Start]);
  3017.         }
  3018.     }
  3019.     if (ControlWindow) {
  3020.         // Menus and gadgets on
  3021.         OnMenu(ControlWindow,FULLMENUNUM(M_PROJECT,NOITEM,NOSUB));
  3022.         OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,NOITEM,NOSUB));
  3023.         OnMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,NOITEM,NOSUB));
  3024.         OnGadget(&OneGadget,ControlWindow,NULL);
  3025.         OnGadget(&TwoGadget,ControlWindow,NULL);
  3026.         OnGadget(&RelGadget,ControlWindow,NULL);
  3027.         OnGadget(&MyAddGadget,ControlWindow,NULL);
  3028.         OnGadget(&DelGadget,ControlWindow,NULL);
  3029.         OnGadget(&LinkGadget,ControlWindow,NULL);
  3030.         OnGadget(&UnlinkGadget,ControlWindow,NULL);
  3031.         OnGadget(&NoneGadget,ControlWindow,NULL);
  3032.         if ((SinglePicture == 2) || (SinglePicture == 3)) {
  3033.             if (FrameNumber > Start) {
  3034.                 OnGadget(&stGadget,ControlWindow,NULL);
  3035.                 OnGadget(&prevGadget,ControlWindow,NULL);
  3036.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_FIRST));
  3037.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_PREV));
  3038.             }
  3039.             else {
  3040.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_FIRST));
  3041.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_PREV));
  3042.             }
  3043.             if (FrameNumber < (Start+Frames-1)) {
  3044.                 OnGadget(&nextGadget,ControlWindow,NULL);
  3045.                 OnGadget(&lastGadget,ControlWindow,NULL);
  3046.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_NEXT));
  3047.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_LAST));
  3048.             }
  3049.             else {
  3050.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_NEXT));
  3051.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_LAST));
  3052.             }
  3053.             if (Frames > 1) {
  3054.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_GOTO));
  3055.                 OnGadget(&gotoGadget,ControlWindow,NULL);
  3056.             }
  3057.             else {
  3058.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_GOTO));
  3059.             }
  3060.         }
  3061.         else {
  3062.             OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,NOSUB));
  3063.         }
  3064.     }
  3065.     if (Pic1_Open) {
  3066.      if (!EGS) {
  3067.         // verify, menus and gadgets on
  3068.         IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  3069.                          IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  3070.                          IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
  3071.                          IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  3072.                          IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  3073.                          IDCMP_GADGETHELP;
  3074.         ModifyIDCMP(Pic1.Win,IDCMPFlags);
  3075.         Pic1.Win->Flags |= WFLG_REPORTMOUSE;
  3076. //        OnMenu(Pic1.Win,FULLMENUNUM(0,NOITEM,NOSUB));    // These are now shared menus
  3077. //        OnMenu(Pic1.Win,FULLMENUNUM(1,NOITEM,NOSUB));
  3078. //        OnMenu(Pic1.Win,FULLMENUNUM(2,NOITEM,NOSUB));
  3079.         SetGadgetAttrs(Pic1.Lgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3080.         SetGadgetAttrs(Pic1.Ugad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3081.         SetGadgetAttrs(Pic1.Dgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3082.         SetGadgetAttrs(Pic1.Rgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3083.         SetGadgetAttrs(Pic1.SideGad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3084.         SetGadgetAttrs(Pic1.BotGad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3085.         RefreshGadgets(Pic1.BotGad,Pic1.Win,NULL);
  3086.      }
  3087.      else {
  3088.       EI_ClearPointer(Pic1.EGS_Win);
  3089.      }
  3090.     }
  3091.     if (Pic2_Open) {
  3092.      if (!EGS) {
  3093.         // verify, menus and gadgets on
  3094.         IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  3095.                          IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  3096.                          IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
  3097.                          IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  3098.                          IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  3099.                          IDCMP_GADGETHELP;
  3100.         ModifyIDCMP(Pic2.Win,IDCMPFlags);
  3101.         Pic2.Win->Flags |= WFLG_REPORTMOUSE;
  3102. //        OnMenu(Pic2.Win,FULLMENUNUM(0,NOITEM,NOSUB));    // These are now shared menus
  3103. //        OnMenu(Pic2.Win,FULLMENUNUM(1,NOITEM,NOSUB));
  3104. //        OnMenu(Pic2.Win,FULLMENUNUM(2,NOITEM,NOSUB));
  3105.         SetGadgetAttrs(Pic2.Lgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3106.         SetGadgetAttrs(Pic2.Ugad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3107.         SetGadgetAttrs(Pic2.Dgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3108.         SetGadgetAttrs(Pic2.Rgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3109.         SetGadgetAttrs(Pic2.SideGad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3110.         SetGadgetAttrs(Pic2.BotGad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3111.         RefreshGadgets(Pic2.BotGad,Pic2.Win,NULL);
  3112.      }
  3113.      else {
  3114.       EI_ClearPointer(Pic2.EGS_Win);
  3115.      }
  3116.     }
  3117.     if (Scr) {
  3118.         if (TSMorphWnd) {
  3119.             // Set pointer for Control and both image windows
  3120.             SetMyPointer();
  3121.             /* Turn relevant gadgets back on
  3122.              * Do not enable GetFile gadgets as it causes enforcer hits
  3123.              */
  3124.             if (!ControlWindow) {
  3125.         //        GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileOne],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);    // GetFile gadgets do not like being disabled
  3126.         //        GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileTwo],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3127.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3128.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3129.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3130.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3131.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3132.             }
  3133.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_EditPoints],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3134.         //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile1],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3135.         //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile2],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3136.         //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetSaveName],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3137.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3138.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3139.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3140.             // Menus back on
  3141.             OnMenu(TSMorphWnd,FULLMENUNUM(0,NOITEM,NOSUB));
  3142.             OnMenu(TSMorphWnd,FULLMENUNUM(1,NOITEM,NOSUB));
  3143.             // Pointer back on
  3144.             ClearPointer(TSMorphWnd);
  3145.         }
  3146.         if (TSMorphWnd) {
  3147.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_Help],TSMorphWnd,NULL,
  3148.                                 GTTX_Text,MyGetMsg(MSG_READY), TAG_END );
  3149.         }
  3150.     }
  3151. }
  3152.  
  3153. void
  3154. Vanilla(ULONG code) {
  3155.     switch (code) {
  3156.     // Edit Mode ???? - set the relevant mode
  3157.     case '1':
  3158.         MySetMode(EDIT1);
  3159.         break;
  3160.     case '2':
  3161.         MySetMode(EDIT2);
  3162.         break;
  3163.     case '3':
  3164.         MySetMode(EDITREL);
  3165.         break;
  3166.     case '4':
  3167.         MySetMode(ADD);
  3168.         break;
  3169.     case '5':
  3170.         MySetMode(DELETE);
  3171.         break;
  3172.     case '6':
  3173.         MySetMode(LINK1);
  3174.         break;
  3175.     case '7':
  3176.         MySetMode(UNLINK1);
  3177.         break;
  3178.     case '8':
  3179.         MySetMode(NONE);
  3180.         break;
  3181.     default:
  3182.         break;
  3183.     }
  3184. }
  3185.  
  3186. void
  3187. MouseButtons(struct Picture *pic,ULONG code,ULONG seconds) {
  3188.                 int k;
  3189.                 /* Somebody pressed a button
  3190.                  * If the second is the same as the activate window
  3191.                  * message then ignore this click
  3192.                  */
  3193.                 if (EGS && pic->JustSeconds && (pic->JustSeconds == seconds)) {
  3194.                     pic->JustSeconds = 0;
  3195.                 }
  3196.                 else {
  3197.                     /* otherwise process the mouse click/release */
  3198.                     pic->JustSeconds = 0;
  3199.                     switch (code) {
  3200.                     case SELECTDOWN:
  3201.                         /* Left button pressed
  3202.                          * remember the currentimage positions
  3203.                          * in case Cancelled
  3204.                          */
  3205.                         SelDown = TRUE;
  3206.                         if (!EGS) {
  3207.                             OldLeft = pic->Left;
  3208.                             OldTop = pic->Top;
  3209.                             if (pic == &Pic1) {
  3210.                                 OldLeft1 = Pic2.Left;
  3211.                                 OldTop1 = Pic2.Top;
  3212.                             }
  3213.                             else {
  3214.                                 OldLeft1 = Pic1.Left;
  3215.                                 OldTop1 = Pic1.Top;
  3216.                             }
  3217.                         }
  3218.                         if (Pic1_Open && Pic2_Open) {
  3219.                             // both windows open so action current mode
  3220.                             switch(Mode) {
  3221.                             case EDIT1:
  3222.                                 /* moving points in one window
  3223.                                  * Find point near click
  3224.                                  * erase and draw in new position
  3225.                                  */
  3226.                                 if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  3227.                                     if (pic == &Pic2) {
  3228.                                         DrawPixels(pic,MyPoint->x1,MyPoint->y1,MyPoint);
  3229.                                     }
  3230.                                     else {
  3231.                                         DrawPixels(pic,MyPoint->x,MyPoint->y,MyPoint);
  3232.                                     }
  3233.                                     CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
  3234.                                     CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
  3235.                                     LimitPoints(&CurX,&CurY,pic);
  3236.                                     DrawPixels(pic,CurX,CurY,MyPoint);
  3237.                                 }
  3238.                                 else {
  3239.                                     SelDown = FALSE;
  3240.                                 }
  3241.                                 break;
  3242.                             case EDIT2:
  3243.                                 /* moving points in both windows
  3244.                                  * Find point near click
  3245.                                  * erase and draw in new positions
  3246.                                  */
  3247.                                 if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  3248.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  3249.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  3250.                                     CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
  3251.                                     CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
  3252.                                     LimitPoints(&CurX,&CurY,pic);
  3253.                                     DrawPixels(pic,CurX,CurY,MyPoint);
  3254.                                     if (pic == &Pic1) {
  3255.                                         DrawPixels(&Pic2,CurX,CurY,MyPoint);
  3256.                                     }
  3257.                                     else {
  3258.                                         DrawPixels(&Pic1,CurX,CurY,MyPoint);
  3259.                                     }    
  3260.                                 }
  3261.                                 else {
  3262.                                     SelDown = FALSE;
  3263.                                 }
  3264.                                 break;
  3265.                             case EDITREL:
  3266.                                 /* moving points relatively in both windows
  3267.                                  * Find point near click
  3268.                                  * erase and draw in new positions
  3269.                                  */
  3270.                                 if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  3271.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  3272.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  3273.                                     CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
  3274.                                     CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
  3275.                                     LimitPoints(&CurX,&CurY,pic);
  3276.                                     if (pic == &Pic1) {
  3277.                                         CurX1 = CurX - MyPoint->x + MyPoint->x1;
  3278.                                         CurY1 = CurY - MyPoint->y + MyPoint->y1;
  3279.                                     }
  3280.                                     else {
  3281.                                         CurX1 = CurX - MyPoint->x1 + MyPoint->x;
  3282.                                         CurY1 = CurY - MyPoint->y1 + MyPoint->y;
  3283.                                     }
  3284.                                     LimitPoints(&CurX1,&CurY1,pic);
  3285.                                     DrawPixels(pic,CurX,CurY,MyPoint);
  3286.                                     if (pic == &Pic1) {
  3287.                                         DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
  3288.                                     }
  3289.                                     else {
  3290.                                         DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
  3291.                                     }    
  3292.                                 }
  3293.                                 else {
  3294.                                     SelDown = FALSE;
  3295.                                 }
  3296.                                 break;
  3297.                             case ADD:
  3298.                                 /* Adding point to both windows
  3299.                                  * Draw in both windows
  3300.                                  */
  3301.                                 CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
  3302.                                 CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
  3303.                                 LimitPoints(&CurX,&CurY,pic);
  3304.                                 DrawPixels(pic,CurX,CurY,NULL);
  3305.                                 if (pic == &Pic1) {
  3306.                                     DrawPixels(&Pic2,CurX,CurY,NULL);
  3307.                                 }
  3308.                                 else {
  3309.                                     DrawPixels(&Pic1,CurX,CurY,NULL);
  3310.                                 }    
  3311.                                 break;
  3312.                             case DELETE:
  3313.                                 /* Deleting point from both windows
  3314.                                  * Erase in both windows - if found
  3315.                                  */
  3316.                                 if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  3317.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  3318.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  3319.                                 }
  3320.                                 else {
  3321.                                     SelDown = FALSE;
  3322.                                 }
  3323.                                 break;
  3324.                             case LINK1:
  3325.                                 /* Linking two points
  3326.                                  * Selecting first point
  3327.                                  * If we can find it then check its not already linked to
  3328.                                  * 4 points then set up the new mode - finding 2nd point
  3329.                                  */
  3330.                                 if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  3331.                                     if (MyPoint->NumLinks == MAX_LINKS) {
  3332.                                           SelDown = FALSE;
  3333.                                         XError(pic,MyGetMsg(MSG_4POINTS),MyGetMsg(MSG_OK),NULL,HE_4points);
  3334.                                     }
  3335.                                     else {
  3336.                                           SetWindowTitles(ControlWindow,MyGetMsg(MSG_L2),(UBYTE *)-1);
  3337.                                         Mode = LINK2;
  3338.                                         MyPoint1 = MyPoint;
  3339.                                         SetMyPointer();
  3340.                                     }
  3341.                                 }
  3342.                                 else {
  3343.                                     SelDown = FALSE;
  3344.                                 }
  3345.                                 break;
  3346.                             case UNLINK1:
  3347.                                 /* Unlinking two points
  3348.                                  * Selecting first point
  3349.                                  * If we can find it then check its already linked
  3350.                                  * then set up the new mode - finding 2nd point
  3351.                                  */
  3352.                                 if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  3353.                                     if (MyPoint->NumLinks) {
  3354.                                           SetWindowTitles(ControlWindow,MyGetMsg(MSG_U2),(UBYTE *)-1);
  3355.                                         Mode = UNLINK2;
  3356.                                         MyPoint1 = MyPoint;
  3357.                                         SetMyPointer();
  3358.                                     }
  3359.                                     else {
  3360.                                         SelDown = FALSE;
  3361.                                         XError(pic,MyGetMsg(MSG_NOTLINK),MyGetMsg(MSG_OK),NULL,HE_NotLinked);
  3362.                                     }
  3363.                                 }
  3364.                                 else {
  3365.                                     SelDown = FALSE;
  3366.                                 }
  3367.                                 break;
  3368.                             case LINK2:
  3369.                                 /* Linking two points
  3370.                                  * Selecting 2nd point
  3371.                                  * If we can find it then do some validation
  3372.                                  * then set up the new mode
  3373.                                  */
  3374.                                 if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  3375.                                     if (MyPoint == MyPoint1) {
  3376.                                           SelDown = FALSE;
  3377.                                         XError(pic,MyGetMsg(MSG_LINKSE),MyGetMsg(MSG_OK),NULL,HE_LinkSelf);
  3378.                                     }
  3379.                                     else {
  3380.                                         if (MyPoint1->NumLinks == MAX_LINKS) {
  3381.                                               SelDown = FALSE;
  3382.                                             XError(pic,MyGetMsg(MSG_4POINTS),MyGetMsg(MSG_OK),NULL,HE_4points);
  3383.                                         }
  3384.                                         else {
  3385.                                             for (k = 0;
  3386.                                                   k < MAX_LINKS;
  3387.                                                   k++) {
  3388.                                                 if (MyPoint->p[k] == MyPoint1) {
  3389.                                                       SelDown = FALSE;
  3390.                                                     XError(pic,MyGetMsg(MSG_READYLI),MyGetMsg(MSG_OK),NULL,HE_Linked);
  3391.                                                 }
  3392.                                             }
  3393.                                             if (SelDown) {
  3394.                                                 LinkPoints(MyPoint,MyPoint1);
  3395.                                                 Mode = LINK2A;
  3396.                                             }
  3397.                                         }
  3398.                                     }
  3399.                                 }
  3400.                                 break;
  3401.                             case UNLINK2:
  3402.                                 /* Unlinking two points
  3403.                                  * Selecting 2nd point
  3404.                                  * If we can find it then do some validation
  3405.                                  * then set up the new mode
  3406.                                  */
  3407.                                 if (MyPoint = FindPoint(pic,EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom) >> Zoom,EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  3408.                                     if (MyPoint == MyPoint1) {
  3409.                                         SelDown = FALSE;
  3410.                                         XError(pic,MyGetMsg(MSG_UNLSE),MyGetMsg(MSG_OK),NULL,HE_UnlinkSelf);
  3411.                                     }
  3412.                                     else {
  3413.                                         for (k = 0;
  3414.                                               k < MAX_LINKS;
  3415.                                               k++) {
  3416.                                             if (MyPoint->p[k] == MyPoint1) {
  3417.                                                 SelDown = FALSE;
  3418.                                             }
  3419.                                         }
  3420.                                         if (!SelDown) {
  3421.                                             SelDown = TRUE;
  3422.                                             UnlinkPoints(MyPoint,MyPoint1,TRUE);
  3423.                                             Mode = UNLINK2A;
  3424.                                         }
  3425.                                         else {
  3426.                                             XError(pic,MyGetMsg(MSG_NOTLINK),MyGetMsg(MSG_OK),NULL,HE_NotLinked);
  3427.                                             SelDown = FALSE;
  3428.                                         }
  3429.                                     }
  3430.                                 }
  3431.                                 break;
  3432.                             default:
  3433.                                 // Some other mode?
  3434.                                 break;
  3435.                             }
  3436.                             /* If we are adding a point, or moving a point
  3437.                              * then we may need to scroll the other window
  3438.                              * to get the point in view
  3439.                              * So update the gadgets and check the values set up
  3440.                              */
  3441.                             if ((Mode == ADD) || 
  3442.                                  ((MyPoint) && ((Mode == EDIT2) || (Mode == EDITREL)))) {
  3443.                                 if (pic == &Pic1) {
  3444.                                     pic1 = &Pic2;
  3445.                                 }
  3446.                                 else {
  3447.                                     pic1 = &Pic1;
  3448.                                 }
  3449.                                 if (Mode != EDITREL) {
  3450.                                     // if not edit rel then both points are in the same position
  3451.                                     CurX1 = CurX;
  3452.                                     CurY1 = CurY;
  3453.                                 }
  3454.                                 pic1->XLeft=pic1->Left;
  3455.                                 pic1->XTop=pic1->Top;
  3456.                                 if (!EGS) {
  3457.                                     if ((CurY1<<Zoom) < pic1->Top) {
  3458.                                         pic1->Top = CurY1<<Zoom;
  3459.                                         SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  3460.                                             PGA_Top, pic1->Top, TAG_END);
  3461.                                     }
  3462.                                     if ((CurX1<<Zoom) < pic1->Left) {
  3463.                                         pic1->Left = CurX1<<Zoom;
  3464.                                         SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  3465.                                         PGA_Top, pic1->Left, TAG_END);
  3466.                                     }
  3467.                                     if ((CurY1<<Zoom) > (pic1->Win->GZZHeight+pic1->Top)) {
  3468.                                         pic1->Top = ((CurY1<<Zoom) - pic1->Win->GZZHeight);
  3469.                                         SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  3470.                                             PGA_Top, pic1->Top, TAG_END);
  3471.                                     }
  3472.                                     if ((CurX1<<Zoom) > (pic1->Win->GZZWidth+pic1->Left)) {
  3473.                                         pic1->Left = ((CurX1<<Zoom) - pic1->Win->GZZWidth);
  3474.                                         SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  3475.                                             PGA_Top, pic1->Left, TAG_END);
  3476.                                     }
  3477.                                     checkGadget(pic1);
  3478.                                 }
  3479.                             }
  3480.                         }
  3481.                         break;
  3482.                     case SELECTUP:
  3483.                         /* Left mouse button up
  3484.                          * If we are currently doing something then
  3485.                          * this actually confirms we really want
  3486.                          * to do it, Saved is set to FALSE following any change
  3487.                          */
  3488.                         if (SelDown) {
  3489.                             SelDown = FALSE;
  3490.                             switch(Mode) {
  3491.                             case ADD:
  3492.                                 // Adding a point, Create and add to list
  3493.                                 if (MyPoint = AllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
  3494.                                     MyPoint->x = CurX;
  3495.                                     MyPoint->y = CurY;
  3496.                                     MyPoint->x1 = CurX;
  3497.                                     MyPoint->y1 = CurY;
  3498.                                     MaxWidth = max(CurX,MaxWidth);
  3499.                                     MaxHeight = max(CurY,MaxHeight);
  3500.                                     AddTail(&PointList,(struct Node *)MyPoint);
  3501.                                     Saved = FALSE;
  3502.                                 }
  3503.                                 else {
  3504.                                     XError(pic,MyGetMsg(MSG_MEMPO),MyGetMsg(MSG_OK),NULL,HE_MemNewPoint);
  3505.                                 }
  3506.                                 break;
  3507.                             case EDIT1:
  3508.                                 // Editing one window, update actual point
  3509.                                 if (pic == &Pic2) {
  3510.                                     MyPoint->x1 = CurX;
  3511.                                     MyPoint->y1 = CurY;
  3512.                                 }
  3513.                                 else {
  3514.                                     MyPoint->x = CurX;
  3515.                                     MyPoint->y = CurY;
  3516.                                 }
  3517.                                 Saved = FALSE;
  3518.                                 break;
  3519.                             case EDIT2:
  3520.                                 // Editing two windows, update actual point
  3521.                                 MyPoint->x = CurX;
  3522.                                 MyPoint->y = CurY;
  3523.                                 MyPoint->x1 = CurX;
  3524.                                 MyPoint->y1 = CurY;
  3525.                                 Saved = FALSE;
  3526.                                 break;
  3527.                             case EDITREL:
  3528.                                 // Editing relative, update actual point
  3529.                                 if (pic == &Pic1) {
  3530.                                     CurX1 = CurX - MyPoint->x + MyPoint->x1;
  3531.                                     CurY1 = CurY - MyPoint->y + MyPoint->y1;
  3532.                                     MyPoint->x = CurX;
  3533.                                     MyPoint->y = CurY;
  3534.                                 }
  3535.                                 else {
  3536.                                     CurX1 = CurX - MyPoint->x1 + MyPoint->x;
  3537.                                     CurY1 = CurY - MyPoint->y1 + MyPoint->y;
  3538.                                     MyPoint->x1 = CurX;
  3539.                                     MyPoint->y1 = CurY;
  3540.                                 }
  3541.                                 Saved = FALSE;
  3542.                                 LimitPoints(&CurX1,&CurY1,((pic == &Pic1)?&Pic2:&Pic1));
  3543.                                 if (pic == &Pic1) {
  3544.                                     MyPoint->x1 = CurX1;
  3545.                                     MyPoint->y1 = CurY1;
  3546.                                 }
  3547.                                 else {
  3548.                                     MyPoint->x = CurX1;
  3549.                                     MyPoint->y = CurY1;
  3550.                                 }
  3551.                                 break;
  3552.                             case DELETE:
  3553.                                 // Deleting, delete actual point
  3554.                                 if (MyPoint) {
  3555.                                     DeletePoint(MyPoint);
  3556.                                 }
  3557.                                 Saved = FALSE;
  3558.                                 break;
  3559.                             case LINK2A:
  3560.                                 // Linking, reset window title and pointer
  3561.                                   SetWindowTitles(ControlWindow,MyGetMsg(MSG_L1),(UBYTE *)-1);
  3562.                                 Mode = LINK1;
  3563.                                 Saved = FALSE;
  3564.                                 SetMyPointer();
  3565.                                 break;
  3566.                             case UNLINK2A:
  3567.                                 // Unlinking, reset window title and pointer
  3568.                                   SetWindowTitles(ControlWindow,MyGetMsg(MSG_U1),(UBYTE *)-1);
  3569.                                 Mode = UNLINK1;
  3570.                                 Saved = FALSE;
  3571.                                 SetMyPointer();
  3572.                                 break;
  3573.                             default:
  3574.                                 break;
  3575.                             }
  3576.                         }
  3577.                         break;
  3578.                     case MENUDOWN:
  3579.                     case MENUUP:
  3580.                         /* Menu button pressed
  3581.                          * Cancel any current action
  3582.                          */
  3583.                         if (SelDown) {
  3584.                             SelDown = FALSE;
  3585.                             switch (Mode) {
  3586.                             case ADD:
  3587.                                 /* Adding,
  3588.                                  * erase points
  3589.                                  */
  3590.                                 DrawPixels(&Pic1,CurX,CurY,NULL);
  3591.                                 DrawPixels(&Pic2,CurX,CurY,NULL);
  3592.                                 break;
  3593.                             case EDIT1:
  3594.                                 /* Editing in one window,
  3595.                                  * erase current postion and redraw in original
  3596.                                  */
  3597.                                 DrawPixels(pic,CurX,CurY,MyPoint);
  3598.                                 if (pic == &Pic2) {
  3599.                                     DrawPixels(pic,MyPoint->x1,MyPoint->y1,MyPoint);
  3600.                                 }
  3601.                                 else {
  3602.                                     DrawPixels(pic,MyPoint->x,MyPoint->y,MyPoint);
  3603.                                 }
  3604.                                 break;
  3605.                             case EDIT2:
  3606.                                 /* Editing in both windows,
  3607.                                  * erase current postion and redraw in original
  3608.                                  */
  3609.                                 DrawPixels(&Pic1,CurX,CurY,MyPoint);
  3610.                                 DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  3611.                                 DrawPixels(&Pic2,CurX,CurY,MyPoint);
  3612.                                 DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  3613.                                 break;
  3614.                             case EDITREL:
  3615.                                 /* Editing relatively in both windows,
  3616.                                  * erase current postions and redraw in original
  3617.                                  */
  3618.                                 if (pic == &Pic1) {
  3619.                                     DrawPixels(&Pic1,CurX,CurY,MyPoint);
  3620.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  3621.                                     DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
  3622.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  3623.                                 }
  3624.                                 else {
  3625.                                     DrawPixels(&Pic2,CurX,CurY,MyPoint);
  3626.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  3627.                                     DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
  3628.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  3629.                                 }
  3630.                                 break;
  3631.                             case DELETE:
  3632.                                 /* Deleting points
  3633.                                  * Redraw in original position
  3634.                                  */
  3635.                                 DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  3636.                                 DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  3637.                                 break;
  3638.                             case LINK2A:
  3639.                                 /* Linking points
  3640.                                  * Re-Unlink
  3641.                                  */
  3642.                                 UnlinkPoints(MyPoint,MyPoint1,TRUE);    // no break
  3643.                             case LINK2:
  3644.                                 /* and reset title and pointer */
  3645.                                   SetWindowTitles(ControlWindow,MyGetMsg(MSG_L1),(UBYTE *)-1);
  3646.                                 Mode = LINK1;
  3647.                                 SetMyPointer();
  3648.                                 break;
  3649.                             case UNLINK2A:
  3650.                                 /* Unlinking points
  3651.                                  * re-link
  3652.                                  */
  3653.                                 LinkPoints(MyPoint,MyPoint1);                // no break
  3654.                             case UNLINK2:
  3655.                                 /* and reset title and pointer */
  3656.                                   SetWindowTitles(ControlWindow,MyGetMsg(MSG_U1),(UBYTE *)-1);
  3657.                                 Mode = UNLINK1;
  3658.                                 SetMyPointer();
  3659.                                 break;
  3660.                             default:
  3661.                                 // some other mode?
  3662.                                 break;
  3663.                             }
  3664.                             if (!EGS) {
  3665.                                 /* Scroll the images back to
  3666.                                  * their original position
  3667.                                  */
  3668.                                 pic->XLeft=pic->Left;
  3669.                                 pic->XTop=pic->Top;
  3670.                                 pic->Left=OldLeft;
  3671.                                 pic->Top=OldTop;
  3672.                                 SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  3673.                                     PGA_Top, pic->Top, TAG_END);
  3674.                                 SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  3675.                                     PGA_Top, pic->Left, TAG_END);
  3676.                                 checkGadget(pic); 
  3677.                                 if (pic == &Pic1) {
  3678.                                     pic1 = &Pic2;
  3679.                                 }
  3680.                                 else {
  3681.                                     pic1 = &Pic1;
  3682.                                 }
  3683.                                 pic1->XLeft=pic1->Left;
  3684.                                 pic1->XTop=pic1->Top;
  3685.                                 pic1->Left=OldLeft1;
  3686.                                 pic1->Top=OldTop1;
  3687.                                 SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  3688.                                     PGA_Top, pic1->Top, TAG_END);
  3689.                                 SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  3690.                                     PGA_Top, pic1->Left, TAG_END);
  3691.                                 checkGadget(pic1); 
  3692.                             }
  3693.                         }
  3694.                         break;
  3695.                     default:
  3696.                         // Some other mouse button?
  3697.                         break;
  3698.                     }
  3699.                 }
  3700. }
  3701.  
  3702. void
  3703. MouseMove(struct Picture *pic) {
  3704.                 /* The mouse moved
  3705.                  * If we are currently doing something
  3706.                  * then update
  3707.                  */
  3708.                 if (SelDown) {
  3709.                     OldX = CurX;
  3710.                     OldY = CurY;
  3711.                     CurX=EGS?pic->EGS_Win->MouseX:(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
  3712.                     CurY=EGS?pic->EGS_Win->MouseY:(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
  3713.                     LimitPoints(&CurX,&CurY,pic);
  3714.                     switch(Mode) {
  3715.                     case EDIT1:
  3716.                         /* Editing one window
  3717.                          * Erase old position
  3718.                          */
  3719.                         DrawPixels(pic,OldX,OldY,MyPoint);
  3720.                         break;
  3721.                     case ADD:
  3722.                         /* Adding
  3723.                          * Erase old positions
  3724.                          */
  3725.                         DrawPixels(&Pic1,OldX,OldY,NULL);
  3726.                         DrawPixels(&Pic2,OldX,OldY,NULL);
  3727.                         break;
  3728.                     case EDIT2:
  3729.                         /* Editing both windows
  3730.                          * Erase old positions
  3731.                          */
  3732.                         DrawPixels(&Pic1,OldX,OldY,MyPoint);
  3733.                         DrawPixels(&Pic2,OldX,OldY,MyPoint);
  3734.                         break;
  3735.                     case EDITREL:
  3736.                         /* Editing relatively both windows
  3737.                          * Erase old positions
  3738.                          */
  3739.                         OldX1 = CurX1;
  3740.                         OldY1 = CurY1;
  3741.                         CurX1 += (CurX - OldX);
  3742.                         CurY1 += (CurY - OldY);
  3743.                         if (pic == &Pic1){
  3744.                             DrawPixels(&Pic1,OldX,OldY,MyPoint);
  3745.                             DrawPixels(&Pic2,OldX1,OldY1,MyPoint);
  3746.                         }
  3747.                         else {
  3748.                             DrawPixels(&Pic1,OldX1,OldY1,MyPoint);
  3749.                             DrawPixels(&Pic2,OldX,OldY,MyPoint);
  3750.                         }
  3751.                         break;
  3752.                     default:
  3753.                         break;
  3754.                     }
  3755.                     if (!EGS) {
  3756.                         // Scroll the current window if required
  3757.                         pic->XLeft=pic->Left;
  3758.                         pic->XTop=pic->Top;
  3759.                         if ((CurY<<Zoom) < pic->Top) {
  3760.                             pic->Top = (CurY<<Zoom);
  3761.                             SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  3762.                                 PGA_Top, pic->Top, TAG_END);
  3763.                         }
  3764.                         if ((CurX<<Zoom) < pic->Left) {
  3765.                             pic->Left = (CurX<<Zoom);
  3766.                             SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  3767.                                 PGA_Top, pic->Left, TAG_END);
  3768.                         }
  3769.                         if ((CurY<<Zoom) > (pic->Win->GZZHeight+pic->Top)) {
  3770.                             pic->Top = ((CurY<<Zoom) - pic->Win->GZZHeight);
  3771.                             SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  3772.                                 PGA_Top, pic->Top, TAG_END);
  3773.                         }
  3774.                         if ((CurX<<Zoom) > (pic->Win->GZZWidth+pic->Left)) {
  3775.                             pic->Left = ((CurX<<Zoom) - pic->Win->GZZWidth);
  3776.                             SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  3777.                                 PGA_Top, pic->Left, TAG_END);
  3778.                         }
  3779.                         checkGadget(pic);
  3780.                     }
  3781.                     // Draw new positions
  3782.                     switch(Mode) {
  3783.                     case EDIT1:
  3784.                         /* Editing one window
  3785.                          * Draw new position
  3786.                          */
  3787.                         DrawPixels(pic,CurX,CurY,MyPoint);
  3788.                         break;
  3789.                     case ADD:
  3790.                         /* Adding
  3791.                          * Draw new positions
  3792.                          */
  3793.                         DrawPixels(&Pic1,CurX,CurY,NULL);
  3794.                         DrawPixels(&Pic2,CurX,CurY,NULL);
  3795.                         break;
  3796.                     case EDIT2:
  3797.                         /* Editing both windows
  3798.                          * Draw new positions
  3799.                          */
  3800.                         DrawPixels(&Pic1,CurX,CurY,MyPoint);
  3801.                         DrawPixels(&Pic2,CurX,CurY,MyPoint);
  3802.                         break;
  3803.                     case EDITREL:
  3804.                         /* Editing both windows relatively
  3805.                          * Draw new positions
  3806.                          */
  3807.                         LimitPoints(&CurX1,&CurY1,pic);
  3808.                         if (pic == &Pic1){
  3809.                             DrawPixels(&Pic1,CurX,CurY,MyPoint);
  3810.                             DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
  3811.                         }
  3812.                         else {
  3813.                             DrawPixels(&Pic2,CurX,CurY,MyPoint);
  3814.                             DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
  3815.                         }
  3816.                         break;
  3817.                     default:
  3818.                         // Some other mode
  3819.                         break;
  3820.                     }
  3821.                     if (!EGS) {
  3822.                         /* If we are affecting the other window then
  3823.                          * we may need to scroll it
  3824.                          */
  3825.                         if ((Mode == ADD) || (Mode == EDIT2) || (Mode == EDITREL)) {
  3826.                             if (pic == &Pic1) {
  3827.                                 pic1 = &Pic2;
  3828.                             }
  3829.                             else {
  3830.                                 pic1 = &Pic1;
  3831.                             }
  3832.                             if (Mode != EDITREL) {
  3833.                                 // Points both in the same position
  3834.                                 CurX1 = CurX;
  3835.                                 CurY1 = CurY;
  3836.                             }
  3837.                             pic1->XLeft=pic1->Left;
  3838.                             pic1->XTop=pic1->Top;
  3839.                             if ((CurY1<<Zoom) < pic1->Top) {
  3840.                                 pic1->Top = (CurY1<<Zoom);
  3841.                                 SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  3842.                                     PGA_Top, pic1->Top, TAG_END);
  3843.                             }
  3844.                             if ((CurX1<<Zoom) < pic1->Left) {
  3845.                                 pic1->Left = (CurX1<<Zoom);
  3846.                                 SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  3847.                                     PGA_Top, pic1->Left, TAG_END);
  3848.                             }
  3849.                             if ((CurY1<<Zoom) > (pic1->Win->GZZHeight+pic1->Top)) {
  3850.                                 pic1->Top = ((CurY1<<Zoom) - pic1->Win->GZZHeight);
  3851.                                 SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  3852.                                     PGA_Top, pic1->Top, TAG_END);
  3853.                             }
  3854.                             if ((CurX1<<Zoom) > (pic1->Win->GZZWidth+pic1->Left)) {
  3855.                                 pic1->Left = ((CurX1<<Zoom) - pic1->Win->GZZWidth);
  3856.                                 SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  3857.                                     PGA_Top, pic1->Left, TAG_END);
  3858.                             }
  3859.                             // Update image scroll
  3860.                             checkGadget(pic1);
  3861.                         }
  3862.                     }
  3863.                 }
  3864. }
  3865.